题意
判断给定的序列是否形成了Clique(图中的点两两联通),如果形成了Clique完全图判断我们是否能否再加一个点形成Maximal Clique,也就是判断这个Clique是不是这个图的Maximal Clique
思路
- Clique的判断方法:先看Clique里的点是否两两联通
- 是否为最大完全图的方法:枚举不在这个Clique的其他节点,尝试往里面加点,只要有一个点满足就说明我们找到了更大的Clique,就是Not Maximal
代码
#include <iostream>
#include <map>
#include <algorithm>
#include <vector>
using namespace std;
int g[210][210];
// 函数功能是判断能否往这个完全图里面再加一个点形成更大的完全图
bool check(vector<int>& v, int target) {
bool has_edge = true;
for(int i = 0; i < v.size(); i++) {
if(v[i] != target && g[v[i]][target] == 0) {
has_edge = false;
break;
}
}
return has_edge;
}
int main() {
// 数据读入
int nodes, edges;
cin >> nodes >> edges;
int u, v;
for(int i = 0; i < edges; i++) {
cin >> u >> v;
g[u][v] = g[v][u] = 1;
}
// 检查完全图
int queries;
cin >> queries;
vector<int> seq; // 用来存放子图的顶点
int len;
for(int i = 0; i < queries; i++) {
seq.clear();
cin >> len;
seq.resize(len);
map<int, int> mp; // 统计哪些点在子图里
for(int j = 0; j < len; j++) {
cin >> seq[j];
mp[seq[j]] = 1;
}
// 先判断是否为完全图
bool is_clique = true;
for(int j = 0; j < len - 1; j++) {
for(int k = j + 1; k < len; k++) {
if(g[seq[j]][seq[k]] == 0) {
is_clique = false;
break;
}
}
if(!is_clique) break;
}
if(!is_clique) {
cout << "Not a Clique
";
}else{
// 在判断出是完全图的基础上,我们尝试看能不能找到更大的完全图
bool pass = false;
for(int z = 1; z <= nodes; z++) {
if(mp[z] == 0) {
bool flag = check(seq, z);
if(flag) {
pass = true;
break;
}
}
}
if(pass)
cout << "Not Maximal
";
else
cout << "Yes
";
}
}
return 0;
}