直通车
Description
作为一个老司机,开车前最让金金犯难的事就是给乘客们安排座位了,总不 能把俩死对头安排到一起吧!金金决定把这可怕的任务交给你,对任意一对乘客, 请你判断他俩的关系。
Input
输入第一行为三个整数 N, M, K( N 为乘客的数目, 乘客的编号为 1 到 N; M 为已知两两乘客之间的关系数; K 为查询的条数)。 1<=N,M,K<=100。
随后 M 行,每行给出一对乘客之间的关系, 格式为:“ 乘客 1 乘客 2 关系” , 其中“ 关系” 为 1 表示是朋友,为-1 表示是敌人。注意两人不可能既是直接的 朋友又是直接的敌人。
最后 K 行,每行给出一对需要查询的宾客编号。 规定: 朋友的朋友也是朋友(所以两个人可能直接关系上是敌人但间接关系 上是朋友)。但敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人。 也 就是说只有朋友的关系能传递,而敌人的关系则不能。
Output
Sample Input
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
Sample Output
Good job
No problem
OK but...
No way
思路
如果两者之间的关系是朋友,则将他们合并起来,如果两者是敌人,则建立邻接表存取每个人的敌人是谁,在判断二者关系的时候,如果两人是朋友,则在他们各自的邻接表查找有没有对方出现,有的话说明既是朋友,又是敌人。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 105;
int tot = 0,fa[maxn],head[maxn];
struct Edge{
int to,next;
}edge[maxn<<1];
int find(int x)
{
int r = x;
while (r != fa[r]) r = fa[r];
int i = x,j;
while (i != r)
{
j = fa[i];
fa[i] = r;
i = j;
}
return r;
}
void unite(int x,int y)
{
int fx = find(x),fy = find(y);
if (fx == fy) return;
fa[fx] = fy;
}
void addedge(int u,int v)
{
edge[tot].to = v,edge[tot].next = head[u];
head[u] = tot++;
}
int main()
{
//freopen("input.txt","r",stdin);
int N,M,K,x,y,opt,i;
bool flag;
scanf("%d%d%d",&N,&M,&K);
for (i = 0;i <= N;i++) fa[i] = i,head[i] = -1;
while (M--)
{
scanf("%d%d%d",&x,&y,&opt);
if (opt == 1) unite(x,y);
else
{
addedge(x,y);
addedge(y,x);
}
}
while (K--)
{
scanf("%d%d",&x,&y);
if (find(x) == find(y))
{
flag = true;
for (i = head[x];i != -1;i = edge[i].next)
{
if (edge[i].to == y) flag = false;
}
if (flag) printf("Good job\n");
else printf("OK but...\n");
}
else
{
flag = true;
for (i = head[x];i != -1;i = edge[i].next)
{
if (edge[i].to == y) flag = false;
}
if (flag) printf("No problem\n");
else printf("No way\n");
}
}
return 0;
}