POJ 2524 Ubiquitous Religions (并差集)

http://acm.pku.edu.cn/JudgeOnline/problem?id=2524

 

#include <iostream>//对并差集的不熟悉

#include <cstdio>

 

using namespace std;

 

long p[50010],n,m,tmp,rel[50010];

 

long getRoot(long big)//压缩路径+返回根结点

{

         if(p[big]==big) return big;

         else return p[big]=getRoot(p[big]);

}

 

int main()

{

         long small,big,count=0,ans,i,bigRoot,smallRoot;

         while(scanf("%ld%ld",&n,&m),(n||m))

         {

                   for(i=1;i<=n;i++) p[i]=i;

                   while(m--)

                   {

                            scanf("%ld%ld",&small,&big);

                            if(small>big)

                            {

                                     tmp=small;

                                     small=big;

                                     big=tmp;

                            }

                            if(p[big]==big) p[big]=small;

                            else

                            {

                                     bigRoot=getRoot(big);

                                     smallRoot=getRoot(small);?

                                     //合并树的时候,需要找到根结点进行合并,

                                     //每个点要看成一棵树的一部分,不断合并,而不能仅仅看成点

                                    

                                     if(smallRoot<bigRoot) p[bigRoot]=smallRoot;

                                     else p[smallRoot]=bigRoot;

                            }

                   }

                   for(i=1;i<=n;i++) getRoot(i);

                   memset(rel,0,sizeof(rel));

                   for(i=1;i<=n;i++) rel[p[i]]=1;

                   ans=0;

                   for(i=1;i<=n;i++) ans+=rel[i];

                   printf("Case %ld: %ld\n",++count,ans);

         }

         return 0;

}

你可能感兴趣的:(poj)