0
点赞
收藏
分享

微信扫一扫

POJ1703带权并查集(距离或者异或)

题意:
      有两个黑社会帮派,有n个人,他们肯定属于两个帮派中的一个,然后有两种操作
1 D a b 给出a b 两个人不属于同一个帮派
2 A a b 问a b 两个人关系 输出 同一个帮派,不是同一个帮派,或者不确定


思路:  
      比较简单的带权并查集,容易想,方法固定,可以开距离根节点的距离这个权,或者是异或也行(应该是行,没试),如果是距离根节点的话 就是每次D a b 都把a b 看成是距离1,然后接在一起,A a b 时候看是不是同一个祖先,是的话看看距离权值是否奇偶性相同,如果不是同一个祖先就是不确定,还有连接之前记得看看是不是已经是一个祖先了,如果是就不要连接了,不然会把整体的权值弄乱,对于异或的话,直接在奇偶性那改成判断相等就行了。

#include<stdio.h>

#include<string.h>



#define N 100000 + 10



int mer[N];

int s_x[N];



int Finds(int x)

{

if(x == mer[x]) return x;

int t = mer[x];

mer[x] = Finds(mer[x]);

s_x[x] += s_x[t];

return mer[x];

}



int main ()

{

int t ,n ,m ,i ,a ,b;

char str[5];

scanf("%d" ,&t);

while(t--)

{

scanf("%d %d" ,&n ,&m);

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

mer[i] = i ,s_x[i] = 0;



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

{

scanf("%s %d %d" ,str ,&a ,&b);

int x = Finds(a);

int y = Finds(b);

if(str[0] == 'D')

{

if(x == y) continue;

if(s_x[a] >= s_x[b])

{

mer[y] = x;

s_x[y] = s_x[a] - s_x[b] + 1;

}

else

{

mer[x] = y;

s_x[x] = s_x[b] - s_x[a] - 1;

}

}

else

{

if(n == 2 && a != b)

{

printf("In different gangs.");

}

else if(x == y)

{

if(s_x[a] % 2 == s_x[b] % 2)

printf("In the same gang.\n");

else printf("In different gangs.\n");

}

else

{

printf("Not sure yet.\n");

}

}

}

}

return 0;

}






举报

相关推荐

0 条评论