A Bug's Life

题目连接:http://poj.org/problem?id=2492
大意大概解释给你一个t代表多少个case,然后有n个虫子,m个谁喜欢谁,这种虫子跟咱们一个货色只有两种性别,男的,或者是母的,然后就是让你算算有没有高搞基或者是百合。
大体思路就是用并查集,然后用一个数组算这个节点到根节点的长度,然后看相同具有相同祖先的是不是有相同的长度%2.

//昨天心情不大好特别想回家,一下午再看这道题晚上偷懒一直在看视频。。。 //一开始觉得无非就是查看这个节点的深度,然后一直打算用h去计算,后不断地wa然后就想了想h是指该节点到最底下的那个高度,然后就开始用了另一个数组num去储存离跟节点的长度,也就是一直在问冯刚队长的偏移量。另外多说一句题外话昨天赵队长然我很难堪啊= =。。。 
View Code
#include <stdio.h>
 #include <stdlib.h>
 int set[2001],num[2001],h[2001];
 int find(int x)//之前我的并查集的find一直是在用循环来需找根节点,这道题要用递归,因为这个题的find 用while去写的话。。。我不会= =。。。
 {
     if(x!=set[x])
     {
         int y = set[x];
         set[x] = find(set[x]);
         num[x] += num[y];
     }
     return set[x];//记得一定是要返回set[x]因为返回x的话这里的声明是的原值。与while 不一样。
 }
 void merge(int x, int y)
 {
     int a = find(x);
     int b = find(y);
     if(a!= b)
     {
         if(h[a]>h[b])
         {
             set[b] = a;
             num[b] = (num[x]-num[y]+1);//因为h[a]的树比较高,所以这里用num[x]-num[y],事实上如果这个数很大的话我建议加上%2,因为加上%2结果不会改变~;
         }
         else
         {
             set[a] = b;
             num[a] = (num[y]-num[x]+1);
             if(h[a] == h[b])
             h[b]++;
         }
     }
 }
 int main()
 {
     int i, j, m, n,t,a,b,g;
     long k;
     k = 0;
     scanf("%d", &t);
     while(t--)
     {
         k++;
         scanf("%d%d", &n, &m);
         int leap = 1;
         for(i = 1 ; i <= n ; i++)
             set[i] = i,h[i] = 0,num[i] = 0;
         for(i = 1 ; i <= m ; i++)
         {
             scanf("%d%d", &a,&b);
             if(a!=b)
             merge(a,b);
             if(find(a) == find(b)&&num[a]%2==num[b]%2)//同一个根节点跟根节点的距离%2相同
             leap = 0;
         }


         printf("Scenario #%ld:\n",k);
         if(leap)
         printf("No suspicious bugs found!\n");
         else
         printf("Suspicious bugs found!\n");
         if(t!=0)
         printf("\n");

     }
     return 0;
 }

 

posted @ 2012-07-22 17:41  某某。  阅读(252)  评论(0编辑  收藏  举报