题面: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;
}
原文地址:https://www.cnblogs.com/ukcxrtjr/p/11131961.html
时间: 2024-10-10 07:46:35