POJ 2492 A Bug's Life 并查集的应用
题意:有n只虫子,每次给出一对互为异性的虫子的编号,输出是否存在冲突。
思路:用并查集,每次输入一对虫子后就先判定一下。如果两者父亲相同,则说明关系已确定,再看性别是否相同,如果相同则有冲突。否则就将两只虫子并入一个集合。
而性别则是用一个gender数组来维护,每个虫子的gender的值为0或者1。
0表示该虫子的性别与父亲结点的性别相同。
1表示该虫子的性别与父亲结点的性别不同。
这题和poj1703本质上是一样的。1703的题解请点传送门。
另外还有一个疑惑,本题输入量巨大,我用输入加速后反而比用scanf要慢得多,弄不明白为什么。。有知道的大神欢迎来给解答一下。
1 #include<stdio.h> 2 #define maxn 2010 3 int father[maxn], gender[maxn]; 4 int Find(int x) 5 { 6 if (father[x] != x) 7 { 8 int t = father[x]; 9 father[x] = Find(father[x]); 10 gender[x] = (gender[x] + gender[t]) % 2; 11 } 12 return father[x]; 13 } 14 void Merge(int x,int y) 15 { 16 int fx = Find(x); 17 int fy = Find(y); 18 father[fx] = fy; 19 if (gender[y] == 0) 20 gender[fx] = 1 ^ gender[x]; 21 else gender[fx] = gender[x]; 22 } 23 int main() 24 { 25 int t; 26 int cas = 1; 27 //freopen("data.in", "r", stdin); 28 scanf("%d",&t); 29 while (t--) 30 { 31 int n, m; 32 scanf("%d%d",&n,&m); 33 for (int i = 1; i <= n; i++) 34 { 35 father[i] = i; 36 gender[i] = 0; 37 } 38 int ok = 1; 39 while (m--) 40 { 41 int a, b; 42 scanf("%d%d",&a,&b); 43 if (!ok) continue; 44 if (Find(a) != Find(b)) 45 Merge(a, b); 46 else if(gender[a] == gender[b]) 47 ok = 0; 48 } 49 if (ok) printf("Scenario #%d:\nNo suspicious bugs found!\n\n", cas++); 50 else printf("Scenario #%d:\nSuspicious bugs found!\n\n", cas++); 51 } 52 return 0; 53 }