CF 766D 带权并查集

CF 766D 带权并查集

题目大意:
给你N个单词M段关系还有Q个询问,关系包括喜欢和不喜欢;对于输入的每段关系,输出“YES”代表不矛盾,“NO”代表矛盾,若这两个单词没有关系则按输入的关系为它们建立关系并输出YES;对于每个询问,如果这两个单词没关系输出3 同义词输出1 反义词输出2 **【带权并查集裸题】******欢迎大佬多多指教!

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string>
using namespace std;
int n,m,q;
typedef long long LL;
const int N=1e5+10;
int fa[N];
int R[N];                            //设定同义词R[i]=0 反义词R[i]=1
char a[30],b[30];
map<string,int>M;
int fi(int x)                          //路径压缩
{
    if(x!=fa[x])
    {
          int t=fa[x];
        fa[x]=fi(fa[x]);
        R[x]=(R[t]+R[x])%2;
    }
    return fa[x];
}
int main()
{
    while(~scanf("%d%d%d",&n,&m,&q))
    {
        for(int i=1;i<=n;i++)
        {
            fa[i]=i;
            R[i]=0;
        }
        int op;
        for(int i=0;i<n;i++)
        {
            scanf("%s",a);
            M[a]=i+1;                  //字符串转化为数字
        }
        for(int i=0;i<m;i++)
        {
            int fx,fy;
            scanf("%d%s%s",&op,a,b);
            fx=fi(M[a]);
            fy=fi(M[b]);
            if(op==1)
            {
                if(fx==fy)                                                 //祖先相同
                {
                    if((R[M[a]]-R[M[b]]+2)%2==0)
                        printf("YES\n");
                    else
                        printf("NO\n");
                }
                else                                                 //祖先不同 将两棵树连起来
                {
                    fa[fy]=fx;
                    R[fy]=(R[M[b]]-R[M[a]]+2)%2;
                    printf("YES\n");
                }
            }
            else
            {
                if(fx==fy)
                {
                    if((R[M[a]]-R[M[b]]+3)%2==0)
                        printf("YES\n");
                    else
                        printf("NO\n");
                }
                else
                {
                    fa[fy]=fx;
                    R[fy]=(R[M[a]]-R[M[b]]+3)%2;
                    printf("YES\n");
                }
            }
        }
        while(q--)
        {
               scanf("%s%s",a,b);
           int fx=fi(M[a]),fy=fi(M[b]);
           if(fx!=fy)
                printf("3\n");
           else
           {
               printf("%d\n",(R[M[a]]+R[M[b]])%2+1);
           }
        }
    }
}

版权声明:本文为weixin_44937448原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。