并查集的变形使用

题目链接:https://cn.vjudge.net/contest/242366#problem/K

AC代码:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
# define maxn 100000+10
# define  ll long long
#define inf 0x3f3f3f3f
#define ll_inf 0x3f3f3f3f3f3f3f3f
int n,m;
int father[maxn],net[maxn];

void init()
{
    for(int i=1; i<=n; i++)
    {
        father[i]=i;//给每个点进行初始化
        net[i]=0;//0 代表相同,1代表不同,最初的时候自己到自己肯定是相同的    
    }
}
int Find(int t)
{
    int temp=father[t];
    if(t==father[t])return t;//如果是自己到自己,祖先当然是自己
    father[t]=Find(father[t]);//寻找祖先节点
    if(net[t]!=net[temp])
    {
        net[t]=1;
    }
    else net[t]=0;
    return father[t];
}
void change(int t1,int t2,int t3,int t4)
{
    father[t3]=t4;//首先进行归并
    if(net[t1]==net[t2])//如果两个子节点的关系和父亲节点相同的时候,就把两个父亲节点中相对是子节点的bet变为1,否则变为0
    {
        net[t3]=1;
    }
    else net[t3]=0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&n,&m);
        init();
        while(m--)
        {
            char str;
            int u,v;
            getchar();
            scanf("%c %d %d",&str,&u,&v);
            int t1=Find(u);
            int t2=Find(v);
            if(str=='A')
            {
                if(t1!=t2)//如果说这两个人的祖先都不一样,关系肯定确定不了
                {
                    printf("Not sure yet.\n");
                    continue;
                }
                if(net[u]==net[v])//在祖先相同的前提下,都和祖先的和关系相同,那么这俩人肯定是同一个帮派
                {
                    printf("In the same gang.\n");
                }
                else
                {
                    printf("In different gangs.\n");
                }
            }
            else
            {
                if(t1!=t2)
                {
                    change(u,v,t1,t2);
                }
            }
        }
    }
    return 0;
}

 

你可能感兴趣的:(并查集)