http://poj.org/problem?id=1838
题意:有一个直角坐标系,相邻的点可以相连成一块,而且可以将k块相连,求最多有几个点可以连成一块。
思路:先并查集,再排序即可
#include<stdio.h> #include<string.h> #include<math.h> #include<iostream> #include<algorithm> #include<queue> #include<stack> #define mem(a,b) memset(a,b,sizeof(a)) #define ll __int64 #define MAXN 16000 #define INF 0x7ffffff #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; struct Point { int x,y; int id; }; Point p[16000+10]; int fa[16000+10]; int num[16000+10]; int cnt[16000+10]; int n; int cmpx(Point a,Point b) { if(a.x!=b.x) return a.x<b.x; return a.y<b.y; } int cmpy(Point a,Point b) { if(a.y!=b.y) return a.y<b.y; return a.x<b.x; } int find(int a) { if(fa[a]!=a) fa[a]=find(fa[a]); return fa[a]; } void bincha(int a,int b) { int x=find(a); int y=find(b); if(x==y) return ; fa[x]=fa[y]; cnt[y]+=cnt[x]; cnt[x]=0; } int main() { int m; int i,j; while(cin>>n>>m) { for(i=1;i<=n;i++) { cnt[i]=1; fa[i]=p[i].id=i; scanf("%d%d",&p[i].x,&p[i].y); } sort(p+1,p+n+1,cmpx); for(i=1;i<n;i++) { if(p[i].x==p[i+1].x&&p[i+1].y-p[i].y==1&&fa[p[i+1].id]!=fa[p[i].id]) { int pre=fa[p[i].id]; int pre1=fa[p[i+1].id]; fa[p[i+1].id]=fa[p[i].id]; cnt[pre]+=cnt[pre1]; cnt[pre1]=0; } } sort(p+1,p+n+1,cmpy); for(i=1;i<n;i++) { if(p[i].y==p[i+1].y&&p[i+1].x-p[i].x==1&&fa[p[i+1].id]!=fa[p[i].id]) { bincha(p[i+1].id,p[i].id); } } j=0; for(i=1;i<=n;i++) { if(cnt[i]!=0) { num[j++]=cnt[i]; } } sort(num,num+j); j--; int ans=0; while(m--) { ans+=num[j--]; } cout<<ans<<endl; } return 0; }