题面:https://www.luogu.org/problemnew/show/CF766D
本题现将字符串转化为两个元素之间的关系,之后再利用带权并查集的操作进行路径压缩和判断即可,注意这里的种类数为2。
Code:
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int fa[N],rnk[N];
map<string,int>ma;
void Init(int n)
for(int i=0;i<=n;i++)
fa[i]=i;
rnk[i]=0;
int Find(int x)
if(x==fa[x])return x;
int temp=fa[x];
fa[x]=Find(fa[x]);
rnk[x]=(rnk[x]+rnk[temp])%2;
return fa[x];
void Merge(int r,int x,int y)
int rx=Find(x);
int ry=Find(y);
if(rx==ry)return;
fa[rx]=ry;
rnk[rx]=(r+rnk[y]-rnk[x]+2)%2;
int main()
ios::sync_with_stdio(false);
cin.tie(0);
int n,m,q;
cin>>n>>m>>q;
Init(n);
int a;
string s1,s2;
for(int i=0;i<n;i++)
cin>>s1;
ma[s1]=i;
while(m--)
cin>>a>>s1>>s2;
a--;
int rs1=Find(ma[s1]);
int rs2=Find(ma[s2]);
if(rs1!=rs2)
Merge(a,ma[s1],ma[s2]);
cout<<"YES"<<endl;
else
if((rnk[ma[s1]]-rnk[ma[s2]]+2)%2!=a)
cout<<"NO"<<endl;
else cout<<"YES"<<endl;
while(q--)
cin>>s1>>s2;
int rs1=Find(ma[s1]);
int rs2=Find(ma[s2]);
if(rs1!=rs2)cout<<3<<endl;
else cout<<((rnk[ma[s1]]-rnk[ma[s2]]+2)%2+1)<<endl;
return 0;