10.04 T1 数据结构+二分
Description
Input
Output
输出一行一个整数,即答案。
Sample Input
6 3 2 0 3 1 1 3 4 2 0 4 5 5
Sample Output
2
Hint
【数据范围及约定】
80~95分:二分图匹配就可以了
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define N 2000005 5 using namespace std; 6 struct node{ 7 int u,v; 8 }e[N]; 9 int cnt,first[N],nxt[N]; 10 void add(int u,int v){ 11 e[++cnt].u=u; 12 e[cnt].v=v; 13 nxt[cnt]=first[u]; 14 first[u]=cnt; 15 } 16 int vis[N],matching[N]; 17 bool match(int u){ 18 for(int i=first[u];i;i=nxt[i]){ 19 int v=e[i].v; 20 if(vis[v])continue; 21 vis[v]=1; 22 if(!matching[v]||match(matching[v])){ 23 matching[v]=u; 24 return true; 25 } 26 } 27 return false; 28 } 29 int n; 30 int hun(){ 31 int ans=0; 32 for(int i=1;i<=n;i++){ 33 memset(vis,0,sizeof vis); 34 if(match(i))ans++; 35 } 36 return ans; 37 } 38 int A[100005],B[100005],C[100005],D[100005]; 39 int main(){ 40 freopen("guide.in","r",stdin); 41 freopen("guide.out","w",stdout); 42 int num;scanf("%d",&num); 43 scanf("%d",&n); 44 for(int i=1;i<=n;i++){ 45 scanf("%d%d",&A[i],&B[i]); 46 } 47 for(int i=1;i<=n;i++){ 48 scanf("%d%d",&C[i],&D[i]); 49 } 50 for(int i=1;i<=n;i++){ 51 for(int j=1;j<=n;j++){ 52 if(A[i]<=C[j]&&B[i]<=D[j])add(i,j+n),add(j+n,i); 53 } 54 } 55 cout<<hun(); 56 return 0;
100分:把x降序排序,然后逐个加进去,如果是洞口直接扔进去,是旅客就把数据结构里最小的大于它的y取出来匹配就可以了,可以证明最优
树状数组(nlog^2n)
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #define N 1000005 5 using namespace std; 6 struct node{ 7 int x,y,id; 8 }e[N]; 9 bool cmp(const node &a,const node &b){ 10 return a.x>b.x; 11 } 12 int c[N]; 13 int lowbit(int x){ 14 return x&(-x); 15 } 16 int n; 17 void add(int x,int v){ 18 while(x<=200000){ 19 c[x]+=v; 20 x+=lowbit(x); 21 } 22 } 23 int query(int x){ 24 // cout<<"from->"<<x<<'\n'; 25 int ans=0; 26 while(x){//cout<<"from->"<<x<<'\n'; 27 ans+=c[x]; 28 x-=lowbit(x); 29 } 30 // cout<<'\n'; 31 return ans; 32 } 33 int main(){ 34 int num; 35 cin>>num>>n; 36 for(int i=1;i<=n;i++){ 37 cin>>e[i].x>>e[i].y; 38 e[i].x++; 39 e[i].y++; 40 e[i].id=0; 41 } 42 for(int i=1;i<=n;i++){ 43 cin>>e[i+n].x>>e[i+n].y; 44 e[i+n].x++; 45 e[i+n].y++; 46 e[i+n].id=1; 47 } 48 int ans=0; 49 sort(e+1,e+2*n+1,cmp); 50 for(int i=1;i<=2*n;i++){ 51 if(e[i].id) 52 add(e[i].y,1); 53 else{ 54 int l=e[i].y,r=2*n; 55 if(query(r)-query(l-1)==0)continue; 56 int now; 57 while(l<=r){ 58 int mid=l+r>>1; 59 if(query(mid)-query(l-1)==0)l=mid+1; 60 else r=mid-1,now=mid; 61 } 62 add(now,-1); 63 ans++; 64 } 65 } 66 cout<<ans; 67 return 0; 68 }
multiset维护序列O(nlogn):
code:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<set> 5 #define N 1000005 6 using namespace std; 7 struct node{ 8 int x,y,id; 9 }e[N]; 10 bool cmp(const node &a,const node &b){ 11 return a.x>b.x; 12 } 13 int c[N]; 14 int lowbit(int x){ 15 return x&(-x); 16 } 17 int n; 18 void add(int x,int v){ 19 while(x<=200000){ 20 c[x]+=v; 21 x+=lowbit(x); 22 } 23 } 24 int query(int x){ 25 // cout<<"from->"<<x<<'\n'; 26 int ans=0; 27 while(x){//cout<<"from->"<<x<<'\n'; 28 ans+=c[x]; 29 x-=lowbit(x); 30 } 31 // cout<<'\n'; 32 return ans; 33 } 34 multiset<int>check; 35 int main(){ 36 freopen("guide.in","r",stdin); 37 freopen("guide.out","w",stdout); 38 int num; 39 cin>>num>>n; 40 for(int i=1;i<=n;i++){ 41 cin>>e[i].x>>e[i].y; 42 e[i].x++; 43 e[i].y++; 44 e[i].id=0; 45 } 46 for(int i=1;i<=n;i++){ 47 cin>>e[i+n].x>>e[i+n].y; 48 e[i+n].x++; 49 e[i+n].y++; 50 e[i+n].id=1; 51 } 52 int ans=0; 53 sort(e+1,e+2*n+1,cmp); 54 for(int i=1;i<=2*n;i++){ 55 if(e[i].id){ 56 check.insert(e[i].y); 57 } 58 else{ 59 if(!check.empty()){ 60 set<int>::iterator it=check.lower_bound(e[i].y); 61 if(*it>=e[i].y)check.erase(*it),ans++; 62 } 63 } 64 } 65 cout<<ans; 66 return 0; 67 }
over