原题链接
题意:给两个长度为n的序列的坐标,分别为(Ai,Bi),(Ci,Di),求最多有多少对坐标满足Ai
分析:将满足题中条件的坐标对的下标(i,j)存入vector,然后就是匈牙利模板
复杂度:O(n*m) n RT,m为构成的坐标对的数量
模板解释:http://blog.csdn.net/dark_scope/article/details/8880547
可参见:http://blog.csdn.net/feng_zhiyu/article/details/79309746
【匈牙利算法】
代码:
#include
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
#define memc(a,b) memcpy(a,b,sizeof(b))
#define rep(i,a,n) for(int i=a;i///[a,n)
#define pb push_back
#define IO ios::sync_with_stdio(false)
#define fre freopen("in.txt","r",stdin)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double PI=acos(-1.0);
const double E=2.718281828459045;
const double eps=1e-8;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int MOD=1e3;
const int N=1e2+5;
const ll maxn=2e5+5;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
int n,m;
int a[N],b[N],c[N],d[N];
int match[N];
bool vis[N];
vector<int> g[N];
bool dfs(int u)
{
for(auto v:g[u])
{
if(vis[v])
continue;
vis[v]=1;
if(match[v]==-1||dfs(match[v]))
{
match[v]=u;
return true;
}
}
return false;
}
void init()
{
rep(i,0,n+1) g[i].clear();
}
void solve()
{
int ans=0;
mem(match,-1);
rep(i,1,n+1)
{
mem(vis,0);
if(dfs(i))
ans++;
}
cout<int main()
{
IO;
cin>>n;
init();
rep(i,1,n+1) cin>>a[i]>>b[i];
rep(i,1,n+1) cin>>c[i]>>d[i];
rep(i,1,n+1)
{
rep(j,1,n+1)
{
if(a[i]<=c[j]&&b[i]<=d[j])
g[i].pb(j);
}
}
solve();
return 0;
}
好用的C++ tuple 操作解决了为啥写一个普通的贪心不能得到AC的答案。
学习了。
tuple用法:http://blog.csdn.net/feng_zhiyu/article/details/79597824
贪心:
tuple实际上相当于结构体。
【结构体实现】
#include
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
#define memc(a,b) memcpy(a,b,sizeof(b))
#define rep(i,a,n) for(int i=a;i///[a,n)
struct Node
{
int a,b,flag;
bool operator < (const Node& m)const
{
if(a!=m.a) return aelse if(b!=m.b) return belse return flagint n;
set<int>st;
void solve()
{
st.clear();
int ans=0;
for(int i=0;i<2*n;i++)
{
int flag=a[i].flag;
if(!flag)
{
st.insert(a[i].b);
}
else
{
auto it=st.lower_bound(a[i].b);
if(it!=st.begin())
{
st.erase(--it);
ans++;
}
}
}
cout<int main()
{
while(cin>>n)
{
rep(i,0,n)
{
cin>>a[i].a>>a[i].b;
a[i].flag=0;
}
rep(i,n,2*n)
{
cin>>a[i].a>>a[i].b;
a[i].flag=1;
}
sort(a,a+2*n);
solve();
}
return 0;
}
【tuple实现】
复杂度: O(nlogn)
代码:
#include
using namespace std;
#define mem(a,n) memset(a,n,sizeof(a))
#define memc(a,b) memcpy(a,b,sizeof(b))
#define rep(i,a,n) for(int i=a;i///[a,n)
#define pb push_back
#define mkp make_pair
#define mkt make_tuple
#define IO ios::sync_with_stdio(false)
#define fre freopen("in.txt","r",stdin)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double PI=acos(-1.0);
const double E=2.718281828459045;
const double eps=1e-8;
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3f;
const int MOD=1e3;
const int N=1e2+5;
const ll maxn=2e5+5;
const int dir[4][2]= {-1,0,1,0,0,-1,0,1};
int n;
vectorint ,int,int> >vec;
set<int>st;
void solve()
{
int ans=0;
for(auto v: vec)
{
int x,y,c;
tie(x,y,c)=v;
if(c == 0)
{
st.insert(y);
}
else
{
auto it = st.lower_bound(y);
if(it != st.begin())
{
///cout<<(*it);
st.erase(--it);///每次消除的都是当前位置前的一个坐标对,即set内的点,这样也保证是最优的
ans++;
///cout<<" ans="<
}
}
}
cout<void init()
{
vec.clear();
st.clear();
}
int main()
{
//fre;
IO;
while(cin>>n)
{
init();
rep(i,0,n)
{
int a,b;
cin>>a>>b;
vec.pb(mkt(a,b,0));
}
rep(i,0,n)
{
int c,d;
cin>>c>>d;
vec.pb(mkt(c,d,1));
}
sort(vec.begin(),vec.end());
/*for(int i=0; i
solve();
}
return 0;
}
/**
3
2 0
3 1
1 3
4 2
0 4
5 5
3
0 0
1 1
5 2
2 3
3 4
4 5
2
2 2
3 3
0 0
1 1
5
0 0
7 3
2 2
4 8
1 6
8 5
6 9
5 4
9 1
3 7
5
0 0
1 1
5 5
6 6
7 7
2 2
3 3
4 4
8 8
9 9
**/