问题概述: 当地有两个黑帮,A a b表示询问a和b是否属于同一黑帮,D a b表示确定a和b属于不同黑帮,对于每次A
询问,输出它们的关系,具体见样例(POJ1703)
输入样例: 对应输出:
1 Not sure yet.
5 5 In different gangs.
A 1 2 In the same gang.
D 1 2
A 1 2
D 2 4
A 1 4
解析在代码中
#include<stdio.h>
int ufs[100005], rel[100005]; /* ufs[k]中存放的是k的根节点,rel[k]中存放的是k与ufs[k]的关系,0表示两者属于不同类,1表示属于同一类*/
int Find(int x)
{
int temp;
if(ufs[x]==x)
return x;
temp = Find(ufs[x]); /*这个也一定要放在前面,和带权并查集一样*/
rel[x] = (rel[x]+rel[ufs[x]]+1)%2; /*如果x与旧祖先的关系和旧祖先与新祖先的关系都为1或0,则x与新祖先属于同一类,否则属于不同类*/
return ufs[x] = temp;
}
int main(void)
{
int T, a, b, m, n, i, t1, t2;
char ch;
scanf("%d", &T);
while(T--)
{
scanf("%d%d", &n, &m);
for(i=1;i<=n;i++)
ufs[i] = i, rel[i] = 1;
for(i=1;i<=m;i++)
{
scanf(" %c%d%d", &ch, &a, &b);
t1 = Find(a);
t2 = Find(b);
if(ch=='A')
{
if(t1==t2) /*如果它们的祖先是同一个,则他们的关系就已经确定*/
{
if(rel[a]==rel[b])
printf("In the same gang.\n");
else
printf("In different gangs.\n");
}
else
printf("Not sure yet.\n");
} /*PS:题目中不会有不合法的输入*/
else
{
if(t1!=t2) /*如果他们的关系还没有确定*/
{
ufs[t1] = t2; /*连接a和b的祖先t1和t2,其中t2是t1的祖先*/
rel[t1] = (rel[a]+rel[b])%2; /*确认t2和t1的关系*/
}
}
}
}
return 0;
}