HihoCoder-1870 Jin Yong’s Wukong Ranking List(并查集)

时间:2023-03-09 17:44:02
HihoCoder-1870 Jin Yong’s Wukong Ranking List(并查集)

我发现大佬好像都是用拓扑排序写的(本菜鸡不会拓扑哭唧唧

说一下并查集的做法吧...

就是找两人右边的(辣鸡的那个人)那个是否比左边厉害,厉害的话就矛盾。

如果他俩没比较过就把厉害的并到辣鸡的。

(辣鸡的是厉害的上一级

 1 #include<stdio.h>
2 #include<algorithm>
3 #include<string.h>
4 #include<map>
5 #include<iostream>
6 #include<string>
7 using namespace std;
8
9 const int maxn=1010;
10 int par[maxn];
11 char a[maxn],b[maxn];
12 map<string,int> p; //把人名转换成数字表示
13
14 int find(int x) //并查集板子
15 {
16 while(x!=par[x]) x=par[x];
17 return x;
18 }
19
20 void unionn(int a,int b)
21 {
22 int fa=find(a);
23 int fb=find(b);
24 if(fa!=fb) par[fa]=fb;
25 }
26
27 int main()
28 {
29 int t;
30 while(scanf("%d",&t)!=EOF){
31 for(int i=1;i<=1000;i++){
32 par[i]=i;
33 }
34 p.clear(); //初始化
35 int cnt=1; //从1开始标记
36 int flag=1,g=1; //flag整体是否有矛盾出现 g本次是否矛盾
37 while(t--){
38 string a,b;
39 cin>>a>>b;
40 if(!p[a]) p[a]=cnt++; //如果这个名字没出现就赋一个新的值
41 if(!p[b]) p[b]=cnt++;
42 int k=20;    //不超过20条(再大也行反正20之前迟早会break的:)
43 while(k--){
44 int s=find(p[b]);
45 if(s==p[b]) break; //如果b的上一级的上一级是b自己 b还没被比较
46 if(s==p[a]) {g=0; break;} //b的上一级的上一级的上一级的....看是否是a 是的话矛盾标记
47 }
48 if(g) unionn(p[a],p[b]);   //左边的是右边下一级
49 else cout<<a<<' '<<b<<endl,flag=0,g=1; //有矛盾出现 flag标记 g要初始化否则下一次可能会出错
50 }
51 if(flag) printf("0\n");
52 }
53 return 0;
54 }