分析:
- 判断是否是团
clique
,即如果任意两个点之间都有边相连则是团,否则就不是团 - 再判断是否是最大团
maximal
,即遍历所有不在集合中的剩余的点,看是否存在集合外的点满足和集合中所有的结点相连,如果存在一个这样的点就不是最大团Maximal clique
- 题目中的数据范围较小,可以直接使用邻接表的方式存储图
通过代码:
#include <iostream>
#include <cstring>
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()
{
cin >> n >> m;
while (m -- )
{
int a, b;
cin >> a >> b;
g[a][b] = g[b][a] = true;
}
int k;
cin >> k;
while (k -- )
{
int cnt;
cin >> cnt;
for (int i = 0; i < cnt; i ++ ) cin >> vers[i];
if (check_clique(cnt))
{
if (check_maximum(cnt)) puts("Yes");
else puts("Not Maximal");
}
else puts("Not a Clique");
}
return 0;
}