4278. 峰会

这篇博客探讨了如何使用图论和图形算法来分析社交网络中的朋友关系。通过建立首脑之间的朋友关系网络,文章介绍了如何判断在峰会上首脑们是否能组成合理的休息区域。内容包括识别完全连接的子图(社团)以及评估是否可以接纳更多的成员。
摘要由CSDN通过智能技术生成

峰会是国家元首或政府首脑的会议。

为峰会安排休息区可不是一件简单的工作。

一共有 N 个首脑参加峰会,编号 1∼N。

这些首脑之间存在 M 对两两之间的直接朋友关系。

在划分区域时,我们希望被安排在同一休息区域的首脑们满足,任意两人之间都是直接朋友关系。

现在,给定 K 个关于划分休息区域的安排,请你依次判断每个安排是否合理。

输入格式

第一行包含两个整数 N 和 M。

接下来 M 行,每行包含两个整数 a,b,表示首脑 a 和首脑 b 之间存在直接朋友关系。

再一行包含整数 K。

接下来 K 行,每行描述一个区域安排,首先包含一个整数 L,表示该安排打算将 L 个首脑安排在同一区域休息,然后包含 L 个整数,表示这些首脑的编号。

输出格式

共 K 行,第 i 行输出对第 i 个安排的判断,具体格式为

如果安排满足其中的任意两人之间都是直接朋友关系并且不存在额外的人与被安排的所有人都是直接朋友关系(即无法安排更多的人在这一区域休息),则输出 Area X is OK.
如果安排满足其中的任意两人之间都是直接朋友关系并且存在额外的人与被安排的所有人都是直接朋友关系(即可以安排更多的人在这一区域休息),则输出 Area X may invite more people, such as H.,其中 H 是额外可被安排的人的编号(如果不唯一,则输出最小的那个)。
如果安排无法满足其中的任意两人之间都是直接朋友关系,则输出 Area X needs help.。
X 表示组别编号,从 1 到 K。

数据范围

1≤N≤200,
1≤M≤N(N−1)2,
1≤a,b≤N,
a≠b,
1≤K≤100,
1≤L≤N,
同一对直接朋友关系不会在输入中重复出现。

输入样例:
8 10
5 6
7 8
6 4
3 6
4 5
2 3
8 2
2 7
5 3
3 4
6
4 5 4 3 6
3 2 8 7
2 2 3
1 1
2 4 6
3 3 2 1
输出样例:
Area 1 is OK.
Area 2 is OK.
Area 3 is OK.
Area 4 is OK.
Area 5 may invite more people, such as 3.
Area 6 needs help.
代码:
#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 210;

int n, m;
bool g[N][N];
bool st[N];

int main()
{
    scanf("%d%d", &n, &m);
    while (m--)
    {
        int a, b;
        scanf("%d%d", &a, &b);
        g[a][b] = g[b][a] = true;
    }

    scanf("%d", &m);
    for (int T = 1; T <= m; T++)
    {
        int cnt;
        scanf("%d", &cnt);
        memset(st, 0, sizeof st);
        while (cnt--)
        {
            int x;
            scanf("%d", &x);
            st[x] = true;
        }

        bool is_clique = true;
        for (int i = 1; i <= n; i++)
            for (int j = i + 1; j <= n; j++)
                if (st[i] && st[j] && !g[i][j])
                    is_clique = false;
        if (!is_clique)
            printf("Area %d needs help.\n", T);
        else
        {
            int id = 0;
            for (int i = 1; i <= n; i++)
                if (!st[i])
                {
                    bool all = true;
                    for (int j = 1; j <= n; j++)
                        if (st[j] && !g[i][j])
                        {
                            all = false;
                            break;
                        }
                    if (all)
                    {
                        id = i;
                        break;
                    }
                }
            if (id)
                printf("Area %d may invite more people, such as %d.\n", T, id);
            else
                printf("Area %d is OK.\n", T);
        }
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追寻远方的人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值