Codeforce -Mahmoud and a Dictionary

题意:

给出n个单词,m条插入,每条插入包括两个单词,和单词之间的关系(近义词,反义词),

如果目前要插入的和已知的相矛盾,则取消插入

q条询问,询问两个单词的关系,近义词输出1,反义词输出2,不知道输出3

题解:

用并查集来做,如果两个词是近义词,则合并(a,b)和(a+n,b+n),如果是反义词则合并(a,b+n)和(a+n,b)

如果两个词有相同的父节点,也就是(a,b)在一组或者(a+n,b+n)在一组,则输出1,

如果(a,b+n)或者(a+n,b)在一组,则输出2,此外输出3

 1 # include <cstdio>
 2 # include <iostream>
 3 # include <cstring>
 4 # include <algorithm>
 5 # include <map>
 6 # include <string>
 7 using namespace std;
 8 
 9 const int maxn=1e5+5;
10 int n,m,q;
11 int c;
12 string a,b;
13 map <string,int> mm;
14 int par[maxn*3+5];
15 int mark[maxn];
16 
17 int findd(int x){
18     if(par[x]==x) return x;
19     else return par[x]=findd(par[x]);
20 }
21 
22 void unit(int x,int y){
23     x=findd(x);
24     y=findd(y);
25     par[x]=y;
26 }
27 
28 bool same(int x,int y){
29     return findd(x)==findd(y);
30 }
31 
32 int main(){
33     while(scanf("%d%d%d",&n,&m,&q)!=EOF){
34         for(int i=1;i<=n;i++){
35             cin>>a;
36             mm[a]=i;
37             par[i]=i;
38             par[i+n]=i+n;
39         }
40         memset(mark,0,sizeof(mark));
41         for(int i=1;i<=m;i++){
42             cin>>c>>a>>b;
43             if(c==1) {
44                 if(same(mm[a],mm[b]+n)) {
45                     printf("NO\n");
46                     continue;
47                 }
48                 if(same(mm[a]+n,mm[b])) {
49                     printf("NO\n");
50                     continue;
51                 }
52                 printf("YES\n");
53                 unit(mm[a]+n,mm[b]+n);
54                 unit(mm[a],mm[b]);
55                 mark[mm[a]]=mark[mm[b]]=1;
56                 //cout<<par[1]<<par[2]<<par[3]<<endl;
57             }
58             else {
59                 if(same(mm[a],mm[b])) {
60                     printf("NO\n");
61                     continue;
62                 }
63                 if(same(mm[a]+n,mm[b]+n)) {
64                     printf("NO\n");
65                     continue;
66                 }
67                 printf("YES\n");
68                 unit(mm[a]+n,mm[b]);
69                 unit(mm[a],mm[b]+n);
70                 mark[mm[a]]=mark[mm[b]]=1;
71                 //cout<<par[1]<<par[2]<<par[3]<<endl;
72             }
73         }
74         for(int i=1;i<=q;i++){
75             cin>>a>>b;
76             if(same(mm[a],mm[b])) printf("1\n");
77             else if(same(mm[a],mm[b]+n)||same(mm[a]+n,mm[b]))printf("2\n");
78             else printf("3\n");
79         }
80     }
81     return 0;
82 }
View Code

 

posted @ 2017-07-08 10:08  林探惜  阅读(133)  评论(0编辑  收藏  举报