这一类的题目都是n个东西属于不同的集合,集合中的情况要么同时发生,要么同时不发生。
poj 1182 是书上的题目,有详解
poj 1703 和 hdu 1829 都是只有两个集合
poj 1703
#include <cstdio>
const int N = 1e5 * 2 + 10;
char s[2];
int n,m,x,y,fa[N],t;
int find(int x){
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
void Union(int x,int y){
x = find(x) ; y =find(y);
fa[x] = y;
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i = 1;i<=2*n;i++) fa[i] = i;
for(int i = 0 ;i<m;i++){
scanf("%s%d%d",s,&x,&y);
if(s[0] == 'D') {
Union(x,y+n);
Union(x+n,y);
}
else {
if(find(x) == find(y) || find(x+n) == find(y+n))
printf("In the same gang.\n");
else if(find(x+n) == find(y) || find(x) == find(y + n))
printf("In different gangs.\n");
else printf("Not sure yet.\n");
}
}
}
return 0;
}
hdu 1829
#include <cstdio>
const int N = 2000 * 2 + 10;
int fa[N],n,q,x,y,t,cas,tt;
int find(int x){
return x == fa[x] ? x :fa[x] = find(fa[x]);
}
void Union(int x,int y){
x = find(x) ; y = find(y);
fa[x] = y;
}
int main(){
scanf("%d",&tt);
while(tt--) {
scanf("%d%d",&n,&t);
for(int i = 1;i<=2*n;i++) fa[i] = i;
int flag = 0;
for(int i = 0;i<t;i++) {
scanf("%d%d",&x,&y);
if(flag) continue;
if(find(x) == find(y) || find(x + n) == find(y + n)) {
flag = 1;
continue;
}
Union(x,y+n);
Union(x+n,y);
}
printf("Scenario #%d:\n",++cas);
if(flag) printf("Suspicious bugs found!\n");
else printf("No suspicious bugs found!\n");
printf("\n");
}
return 0;
}