题意:一个字典有n个单词,有m个关系表示单词之间是同义还是反义,如果关系可行输出YES如果与前面可行的关系有冲突输出NO,最后k个询问2个单词之间的关系,同义输出1,反义输出2,否则输出3
思路:还是带权或者拆点并查集,如果是有冲突的关系那么不加入并查集
AC代码:
#include "iostream" #include "string.h" #include "stack" #include "queue" #include "string" #include "vector" #include "set" #include "map" #include "algorithm" #include "stdio.h" #include "math.h" #define ll long long #define bug(x) cout<<x<<" "<<"UUUUU"<<endl; #define mem(a) memset(a,0,sizeof(a)) #define mp(x,y) make_pair(x,y) #define pb(x) push_back(x) using namespace std; const long long INF = 1e18+1LL; const int inf = 1e9+1e8; const int N=1e5+100; const ll mod=1e9+7; map<string,int> M; string s,s0; int n,m,q,pre[N<<2]; void init(int n){ for(int i=0; i<+2*n; ++i) pre[i]=i; } int finds(int x){ return pre[x]=pre[x]==x?x:finds(pre[x]); } void unions(int x, int y){ int fx=finds(x), fy=finds(y); pre[fy]=fx; } int main(){ ios::sync_with_stdio(false),cin.tie(0),cout.tie(0); cin>>n>>m>>q; init(n); for(int i=1; i<=n; ++i){ cin>>s; M[s]=i; } int t; for(int i=1; i<=m; ++i){ cin>>t>>s>>s0; int x=M[s], y=M[s0]; if(t==1){ if(finds(x)==finds(y+n) || finds(y)==finds(x+n)){ cout<<"NO\n"; continue; } else{ cout<<"YES\n"; unions(x,y); unions(x+n,y+n); } } else{ if(finds(x)==finds(y) || finds(x+n)==finds(y+n)){ cout<<"NO\n"; continue; } else{ cout<<"YES\n"; unions(x,y+n); unions(y,x+n); } } } for(int i=1; i<=q; ++i){ cin>>s>>s0; int x=M[s], y=M[s0]; if(finds(x)==finds(y)) cout<<"1\n"; else if(finds(x+n)==finds(y)) cout<<"2\n"; else cout<<"3\n"; } return 0; }