Mahmoud and a Dictionary CodeForces

来源:互联网 发布:汉王文本王扫描仪软件 编辑:程序博客网 时间:2024/06/05 10:32

题意

给出多个字符串 然后再输入多个字符串之间的关系 让我们判断这其中是否存在矛盾的关系 有矛盾输出NO 没矛盾输出 YES
然后再输入多个询问 每个询问 两个字符串 让我们判断其中的关系 同义词输出1 反义词输出2 不确定输出3

分析

种类并查集

如果两个字符串的关系 是1 表示同义
那么分情况讨论 如果两个词的根节点相同 那么表示有关系 那么如果与根节点的关系是相同的那么没错 如果与根节点的关系是不同的 那么有错
如果两个词的根节点不同 那么表示没关系 把他们的根节点连到一起
我们用0表示同义词 1表示反义词 当输入ab关系为1时
a 1 0 1 0
b 0 1 1 0 那么 对应的根节点关系可知
为0 0 1 1
当输入ab关系为0时
a 1 0 1 0
b 0 1 1 0 那么对应根节点关系
为1 1 0 0
当两个字符串输入关系为2时
那么如果两个字符根节点不同 那么就把他们连一起 新根节点关系可以有上面的统计结果分析得出
当两个字符串与根节点相同 那么如果他们与根的关系不同 那么没错 如果相同就有矛盾

code

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 1e5+7;char a[22],b[22];map<string,int>M;int f[maxn],rel[maxn];int find(int x){    int t;    if(x==f[x])return x;    t = find(f[x]);    rel[x] = (rel[f[x]]+rel[x]+1)%2;    return f[x] = t;}int main(){    int n,m,q;    scanf("%d%d%d",&n,&m,&q);    for(int i=1;i<=n;i++){        scanf("%s",a);        M[a]=i;    }    for(int i=1;i<=n;i++)f[i] = i,rel[i] = 1;    while(m--){        int F;        scanf("%d%s%s",&F,a,b);        int ta,tb,fa,fb;        ta = M[a];        tb = M[b];        fa = find(ta);        fb = find(tb);        if(F==1){            if(fa==fb){                if(rel[ta]==rel[tb])puts("YES");                else puts("NO");            }            else{                f[fa] = fb;                rel[fa] = (rel[ta]+rel[tb]+1)%2;                puts("YES");            }        }        else{            if(fa==fb){                if(rel[ta]==rel[tb])puts("NO");                else puts("YES");            }            else{                f[fa] = fb;                rel[fa] = rel[ta]^rel[tb];                puts("YES");            }        }    }    while(q--){        scanf("%s%s",a,b);        int ta  = M[a];        int tb  = M[b];        int fa = find(ta);        int fb = find(tb);        if(fa!=fb)puts("3");        else if(rel[ta]==rel[tb])puts("1");        else puts("2");    }    return 0;}