hdu 4619 Warm up 2(并查集)
把相互覆盖的骨牌放入一个集合中,如果一个集合有cnt 个元素 那么这个集合所在区域最多只能存在 (cnt +1)/2 个元素。
#include <iostream> #include <cstdio> using namespace std; int father[2005]; int cnt[2005]; int vis[105][105]; void init(int n) { int i; for(i=1;i<=n;i++) { father[i]=i; cnt[i]=0; } } int find(int x) { while(father[x]!=x) x=father[x]; return x; } void merge(int x,int y) { int xx=find(x); int yy=find(y); if(xx==yy)return; father[xx]=yy; } int main() { int n,m; while(scanf("%d%d",&n,&m)!=EOF) { if(!n && !m)break; memset(vis,0,sizeof(vis)); init(n+m); for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); vis[y][x]=vis[y][x+1]=i; } for(int i=n+1;i<=n+m;i++) { int x,y; scanf("%d%d",&x,&y); if(vis[y][x]!=0)merge(i,vis[y][x]); if(vis[y+1][x]!=0)merge(i,vis[y+1][x]); } for(int i=1;i<=m+n;i++) { int rt=find(i); cnt[rt]++; } int ans=0; for(int i=1;i<=m+n;i++) { ans+=((cnt[i]+1)/2); } printf("%d\n",ans); } return 0; }