当前位置: 代码迷 >> 综合 >> HDU - 1213 How Many Tables(并查集)
  详细解决方案

HDU - 1213 How Many Tables(并查集)

热度:2   发布时间:2023-11-25 07:20:09.0

HDU - 1213 How Many Tables(并查集)

#include <stdio.h> 
int f[1010],n,m; 
//这里是初始化,非常地重要,数组里面存的是自己数组下标的编号就好了。 
void init()   
{
       for(int i=1;i<=n;i++) f[i]=i;
}   
//这是找爹的递归函数,不停地去找爹,直到找到祖宗为止,其实就是去找犯罪团伙的最高领导人,
//“擒贼先擒王”原则。
int getf(int v)   
{
       if(f[v]==v) return v;   else  {
       //这里是路径压缩,每次在函数返回的时候,顺带把路上遇到的人的“BOSS”改为最后找//到的祖宗编号,也就是犯罪团伙的最高领导人编号。这样可以提高今后找到犯罪团伙的//最高领导人(其实就是树的祖先)的速度。f[v]=getf(f[v]);//这里进行了路径压缩return f[v];}   
}   //请从此处开始阅读程序,从主函数开始阅读程序是一个好习惯。
int main()   
{
    int t;scanf("%d",&t);while(t--){
    scanf("%d %d",&n,&m);   init();  //初始化是必须的for(int i=1;i<=m;i++)   {
       int x,y;scanf("%d %d",&x,&y);//开始合并犯罪团伙 int t1=getf(x);//t1、t2分别为x和y的大BOSS(首领),int t2=getf(y);//每次双方的会谈都必须是各自最高领导人才行if(t1!=t2) f[t2]=t1;//判断两个结点是否在同一个集合中,即是否为同一个祖先。}//“靠左”原则,左边变成右边的BOSS。即把右边的集合,作为左边集合的子集合。//最后扫描有多少个独立的犯罪团伙int sum=0;for(int i=1;i<=n;i++)if(f[i]==i)sum++;printf("%d\n",sum);} return 0;   
}
  相关解决方案