【题解】【AcWing】1635. 最大团

本文解析了如何使用C++实现判断无向图中特定顶点子集是否构成最大团的问题,涉及图的构建、团的定义、检查和最大团的判定技巧。通过实例演示了解如何判断是否为最大团并输出相应的结论。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1635. 最大团

原题传送:AcWing 1635. 最大团

在一个无向图中,如果一个顶点子集满足子集内的任意两个不同顶点之间都是相连的,那么这个顶点子集就被称为一个团。

如果一个团不能通过加入某个新的顶点来扩展成一个更大的团,那么该团就被称为最大团。

现在,你需要判断给定顶点子集能否构成一个最大团。

输入格式

第一行包含两个整数 N v N_v Nv N e N_e Ne ,分别表示无向图中点和边的数量。

接下来 N e N_e Ne 行,每行包含两个整数 a , b a,b a,b ,表示点 a a a 和点 b b b 之间存在一条边。

所有点的编号从 1 1 1 N v N_v Nv

再一行,包含整数 M M M ,表示询问次数。

接下来 M M M 行,每行描述一个询问顶点子集,首先包含一个整数 K K K ,表示子集包含点的数量,然后包含 K K K 个整数,表示 K K K 个不同顶点的编号。

一行中所有数字之间用一个空格隔开。

输出格式

每组询问在一行中输出一个结论。

如果给定子集是最大团,则输出Yes,如果是一个团,但不是最大团,则输出Not Maximal,如果根本不是团,则输出Not a Clique

数据范围

1 ≤ N v ≤ 200 1 \le N_v \le 200 1Nv200 ,
1 ≤ N e ≤ N v ( N v − 1 ) 2 1 \le N_e \le \frac{N_v(N_v-1)}{2} 1Ne2Nv(Nv1) ,
1 ≤ M ≤ 100 1 \le M \le 100 1M100 ,
1 ≤ K ≤ N v 1 \le K \le N_v 1KNv

输入样例:
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
3 4 3 6
3 3 2 1
输出样例:
Yes
Yes
Yes
Yes
Not Maximal
Not a Clique
思路:

建立图,遍历查询的所有点对,若存在无边的点对,则不是团。如果是团,遍历集合外的点能否和集合内的所有点有边,若有边,则当前团不是最大团。

题解:
#include <bits/stdc++.h>

using namespace std;

const int N = 210;

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

bool check_clique(int cnt)
{
	for(int i = 0; i < cnt; i++)
		for(int j = 0; j < i; j++)
			if(!g[vers[i]][vers[j]])
				return false;
	return true;
}

bool check_maximum(int cnt)
{
	memset(st, 0, sizeof st);
	for(int i = 0; i < cnt; i++)
		st[vers[i]] = true;

	for(int i = 1; i <= n; i++)
	{
		if(!st[i])
		{
			bool success = true;
			for(int j = 0; j < cnt; j++)
			{
				if (!g[i][vers[j]])
				{
                    success = false;
                    break;
                }
			}
			if(success) return false;
		}
	}
	return true;
}

int main()
{
	scanf("%d%d", &n, &m);
		
	for(int i = 0; i < m; i++)
	{
		int a, b;
		scanf("%d%d", &a, &b);
		g[a][b] = g[b][a] = true;
	}
	
	int k;
	scanf("%d", &k);
	
	while(k--)
	{
		int cnt;
		scanf("%d", &cnt);
		for(int i = 0; i < cnt; i++)
			scanf("%d", &vers[i]);
		if(check_clique(cnt))
		{
			if(check_maximum(cnt))
				printf("Yes\n");
			else
				printf("Not Maximal\n");
		}
		else
			printf("Not a Clique\n");
	}
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值