您的位置:首页 > 其它

poj 1988_并查集(*)

2013-05-02 10:24 288 查看
题目描述:

   。。。。。tle了数次。。。  

解题思路:

  
几个可以看出来属于并查集的题,但是有时效要求。如果没有时效要求的话,一个最直观的方法是可以直接用不压缩的并查集,最后找树的某个节点位于第几层即可;如果压缩的话,也可以加一个down[]数组来存要求的值,在每次做union的时候,把x点放在y点之上时更新所有x点所在子树的所有down值,但是这样更新耗费的时间大,会令整个复杂度就增加为n倍的原并查集的复杂度;因此需要想一想,如果开两个数组up[]和down[],每次union的时候,只更新底层子树根的down值,和底层子树根的up值(也就是每次合并之前,子树根的up和down值都是正确的),然后在最后求的时候,用find_set更新点的up值,令根down值减去节点的up值,即为节点的深度。

代码:

#include <stdio.h>

#include <stdlib.h>

#define N 30001

int set
, down
, up
;

int count, max=1;

int find_set(int x)

{

   int tmp = set[x];

   if(set[x]!=x)

   {

     
set[x] = find_set(set[x]);

     
printf("find_set中更新:up[%d](%d) +=
up[%d](%d).\n",x,up[x],tmp,up[tmp]);

     
up[x] += up[tmp];

     
printf("find_set中更新后:up[%d] = %d.\n",x,up[x]);

   }

   return set[x];

}

void union_set(int x, int y) // m x y

{

   int i;

   int y1 = find_set(y);

   int x1 = find_set(x);

//  
for(i=1;i<=max;i++) 
//x所在的树的每个点的down都要加上 1+down[y1]

//     
if(find_set(i) == x1)

//     
{

//       
// printf("顶层树的%d点的原值(%d) 加上 底层树的最高值(1+y1[%d点]) %d =
",i,down[i],y1,1+down[y1]);

//        
down[i] += 1+down[y1];

//        
//printf("%d.\n",down[i]);

//     
}

   set[y1] = x1;

  
printf("归并%d(x)->%d(y)上,令set[%d](y1) =
%d(x1).\n",x,y,y1,x1);

   printf("更新前:x1:down[%d] =
%d.\ty1:up[%d] = %d,down[%d] =
%d\n",x1,down[x1],y1,up[y1],y1,down[y1]);

   up[y1] += down[x1];

   down[x1] += down[y1];

   printf("更新后:x1:down[%d] =
%d.\ty1:up[%d] = %d,down[%d] =
%d\n",x1,down[x1],y1,up[y1],y1,down[y1]);

}

main()

{

   int p,i,x,y;

   char str[2];

  

  
scanf("%d",&p);

  

  
for(i=1;i<N;i++)

   {

     
set[i] = i;

     
down[i] = 1;

     
up[i] = 0;

   }

  

  
for(i=1;i<=p;i++)

   {

     
scanf("%s",str);

     
if(strcmp("M",str)==0)

     
{

        
scanf("%d %d",&x,&y);

        
max =
max>x?(max>y?max:y):(x>y?x:y);

        
union_set(x,y);

     
}

     
else

     
{

        

        
scanf("%d",&x);

        
count = down[find_set(x)]-up[x];

        
printf("%d\n",count-1);

     
}

   }

   //system("pause");

   return 0;

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: