题意
给出多个字符串 然后再输入多个字符串之间的关系 让我们判断这其中是否存在矛盾的关系 有矛盾输出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;
}