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