POJ - 2236
题意:共有 N 台计算机,每台计算机之间的距离不得大于 d ,
对计算机进行两种操作:
1、O p 修复计算机p
2、S p q 判断两台计算机之间是否可以通信
思路:用二维数组来保存连个计算机时候可以连通(满足距离小于等于 d 即可)
进行第一种操作的时候,需要将可以和 p 连接的计算机连接(距离小于等于 d 并且两个计算机已经修复)
进行第二种操作的时候,判断即可
AC - code
#include<iostream> #include<string> using namespace std; const int MAXN = 1000+10; int map[MAXN][MAXN]={0}; int bin[MAXN]; int vis[MAXN]={0}; struct node{ int x,y; }site[MAXN]; void init(int N){ for(int i=1;i<=N;i++) bin[i]=i; } int find(int a){ return a==bin[a]?a:find(bin[a]); } int cmp(node x,node y,int d){ int ans=(x.x-y.x)*(x.x-y.x)+(y.y-x.y)*(y.y-x.y); if(ans>d*d)return 0; return 1; } int main(){ ios::sync_with_stdio(0); int N,D; cin>>N>>D; init(N); for(int i=0;i<N;i++){ cin>>site[i].x>>site[i].y; } for(int i=0;i<N;i++){ for(int j=i+1;j<N;j++){ if(cmp(site[i],site[j],D)){ map[i+1][j+1]=map[j+1][i+1]=1; } } } string s; while(cin>>s){ if(s[0]=='S'){ int l,r; cin>>l>>r; int xx=find(l); int yy=find(r); if(xx!=yy){ cout<<"FAIL"<<endl; } else cout<<"SUCCESS"<<endl; } else { int x; cin>>x; int xx=find(x); for(int i=1;i<=N;i++){ if(map[x][i]&&vis[i]){ int yy=find(i); if(xx!=yy){ bin[yy]=xx; } } } vis[x]=1; } } return 0; }
POJ - 1611
题意:共有 N 个学生,这些学生中,有一些学生组成了 M 个小组。
各个小组中,有人可能患病,则这个小组所有人就会有人患病。
初始时,编号为 0 的学生患病了,求出 可能患病学生的个数。
思路:典型的并查集(balabala)
AC - code
#include<iostream> using namespace std; const int MAXN = 30000+5; int bin[MAXN]; void init(int N){ for(int i=0;i<=N;i++){ bin[i]=i; } } int find(int a){ return a==bin[a]?a:find(bin[a]); } int main(){ int N,M; ios::sync_with_stdio(0); while(cin>>N>>M){ init(N); if(N==0&&M==0)break; while(M--){ int a; cin>>a; if(a==0)continue; int x,y; cin>>x; a--; int xx=find(x); while(a--){ cin>>y; int yy=find(y); if(xx!=yy){ bin[yy]=xx; } } } int xx=find(0),ans=1; for(int i=1;i<=N;i++){ int yy=find(i); if(xx==yy){ ans++; } } cout<<ans<<endl; } return 0; }
HDU - 1213
题意:和上题相似,上题是判断小组,这题是查找小组的个数