PAT l2-010 排座位 【并查集】

L2-010. 排座位

时间限制
150 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
陈越

布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。

输入格式:

输入第一行给出3个正整数:N(<= 100),即前来参宴的宾客总人数,则这些人从1到N编号;M为已知两两宾客之间的关系数;K为查询的条数。随后M行,每行给出一对宾客之间的关系,格式为:“宾客1 宾客2 关系”,其中“关系”为1表示是朋友,-1表示是死对头。注意两个人不可能既是朋友又是敌人。最后K行,每行给出一对需要查询的宾客编号。

这里假设朋友的朋友也是朋友。但敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人。只有单纯直接的敌对关系才是绝对不能同席的。

输出格式:

对每个查询输出一行结果:如果两位宾客之间是朋友,且没有敌对关系,则输出“No problem”;如果他们之间并不是朋友,但也不敌对,则输出“OK”;如果他们之间有敌对,然而也有共同的朋友,则输出“OK but...”;如果他们之间只有敌对关系,则输出“No way”。

输入样例:
7 8 4
5 6 1
2 7 -1
1 3 1
3 4 1
6 7 -1
1 2 1
1 4 1
2 3 -1
3 4
5 7
2 3
7 2
输出样例:
No problem
OK
OK but...
No way

这题注意题意的理解,敌人的敌人不一定是敌人,所以敌人不具有传递性,不能用并查集。。。直接用数组标记就行了。
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <string>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <map>
 8 #include <queue>
 9 #include <map>
10 using namespace std;
11 //const int inf = 0x3f3f3f3f;
12 typedef long long ll;
13 const int maxn = 111;
14 int mp[maxn][maxn];
15 int preb[maxn];
16 int rkb[maxn];
17 void init(int n)
18 {
19     for(int i=0;i<=n;++i)
20     {
21         rkb[i]=0;
22         preb[i]=i;
23     }
24 }
25 int findb(int x)
26 {
27     if(preb[x]==x)
28         return x;
29     else return preb[x]=findb(preb[x]);
30 }
31 void mixb(int x,int y)
32 {
33     x=findb(x);
34     y=findb(y);
35     if(x==y) return ;
36     if(rkb[x]<rkb[y])
37     {
38         preb[x]=y;
39     }
40     else
41     {
42         preb[y]=x;
43         if(rkb[x]==rkb[y])
44             rkb[x]++;
45     }
46 }
47 int main()
48 {
49     int n,m,k;
50     scanf("%d%d%d",&n,&m,&k);
51     int u,v,s;
52     init(n);
53     for(int i=0;i<m;++i)
54     {
55         scanf("%d%d%d",&u,&v,&s);
56         if(s==-1) mp[u][v]=1,mp[v][u]=1;
57         if(s==1 && findb(u)!=findb(v))
58             mixb(u,v);
59     }
60     int f1=0,f2=0;
61     for(int i=0;i<k;++i)
62     {
63         f1=0;f2=0;
64         scanf("%d%d",&u,&v);
65         if(mp[u][v])    f1=1;
66         if(findb(u)==findb(v))  f2=1;
67         //    printf("%d %d %d %d
",u,v,findb(u),findb(v));
68         if((f1 && f2))
69         {
70             puts("OK but...");
71         }
72         else if(f1 && !f2)
73         {
74             puts("No way");
75         }
76         else if(!f1 && f2)
77         {
78             puts("No problem");
79         }
80         else puts("OK");
81     }
82     return 0;
83 }
View Code
原文地址:https://www.cnblogs.com/zmin/p/8536307.html