PTA 天梯赛 L2-010 排座位

731 阅读3分钟

题目链接

题目描述

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

输入格式:

输入第一行给出3个正整数:N(≤100),即前来参宴的宾客总人数,则这些人从1N编号;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

解题思路

首先,题目很长,我们看过题目后一定要搞清楚要干什么,理清思路,再将代码实现。我做这道题是,没有看完整题目的意思,就去做了,结果输出时遇到问题,又补救代码,浪费时间。

给定N个人,再给出M个两两关系,我们可以用一个二维数组p来记录每两个人之间的关系,默认为0。最主要的部分就是这句话这里假设朋友的朋友也是朋友。但敌人的敌人并不一定就是朋友,朋友的敌人也不一定是敌人。只有单纯直接的敌对关系才是绝对不能同席的。最后输出时也要求我们要判断是否有共同的朋友,所以就用到了并查集的知识。最后就是处理输入输出的问题。

并查集 (对集合进行合并和查询)

int f[1000];//x的父结点

int find(int x)//找祖宗结点 
{ 
    if (f[x] != x) f[x] = find(f[x]); 
    return f[x]; 
}

//初始时,每个结点祖宗结点初始化为自己
for (int i = 1; i <= n; i++) f[i] = i;

//合并集合     如果两人之间是朋友则将两人建立联系。
if (c==1 && f[a] != f[b]) f[find(a)] = find(b);
//查询  两人之间敌对,有公共朋友则输出第一句,没有公共朋友输出第二句。
if (p[a][b] == -1 && find(a) == find(b)) cout << "OK but..."<<endl; 
else if(p[a][b] == -1 && find(a) != find(b)) cout << "No way" << endl;

AC代码

#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
typedef long long ll;
int p[1000][1000] = {0};
int f[1000];//x的父结点

int find(int x)//找祖宗结点
{
    if (f[x] != x) f[x] = find(f[x]);
    return f[x];
}
int main()
{
    int n,m,k;
    cin >> n >> m >> k;
    //每个结点祖宗结点初始化为自己
    for (int i = 1; i <= n; i++) f[i] = i;
    while (m--)
    {
        int a, b, c;
        cin >> a >> b >> c;
        p[a][b] = p[b][a] = c;
        //合并集合
        if (c==1 && f[a] != f[b]) f[find(a)] = find(b);
    }
    while (k--)
    {
        int a, b;
        cin >> a >> b;
        
        if (p[a][b] == 1) cout << "No problem" << endl;
        else if (p[a][b] == 0) cout << "OK" << endl;
        else if (p[a][b] == -1 && find(a) == find(b)) cout << "OK but..."<<endl;
        else if(p[a][b] == -1 && find(a) != find(b)) cout << "No way" << endl;
    }
    return 0;
}