题目链接https://pintia.cn/problem-sets/994805342720868352/problems/994805343979159552
题目大意:给出一个图的边的集合,给出M
个query,每个query是一个点的集合,判断这个点集是否构成Clique,如果是,是否是Maximal Clique(点集内每两个点都有边连接的叫Clique,不能再加入任何一个点的Clique是Maximal Clique)
思路:还以为Clique这些有什么厉害的算法,没想到模拟就行了。。。
judgeClique()
函数返回值含义
-1
:不是Clique0
:是Clique但不是最大1
:是最大Clique
第一个循环判断是否所有点对之间都连接;
第二个循环对点集以外的点v
遍历,如果所有v
都不能加入了,则为最大Clique;否则若至少还有一个点能加入,则仅仅是Clique
int judgeClique() {
for (int i = 0; i < query.size(); i++) {
for (int j = i+1; j < query.size(); j++) {
int u = query[i], v = query[j];
if (!G[u][v])
return -1;
}
}
for (int v = 1; v <= Nv; v++) {
if (!count(query.begin(), query.end(), v)) {
bool flag = true;
for (int i = 0; i < query.size(); i++) {
if (!G[query[i]][v]) {
flag = false;
break;
}
}
if (flag)
return 0;
}
}
return 1;
}
完整代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
using namespace std;
int Nv, Ne;
vector<int> query;
bool G[201][201];
int judgeClique() {
for (int i = 0; i < query.size(); i++) {
for (int j = i+1; j < query.size(); j++) {
int u = query[i], v = query[j];
if (!G[u][v])
return -1;
}
}
for (int v = 1; v <= Nv; v++) {
if (!count(query.begin(), query.end(), v)) {
bool flag = true;
for (int i = 0; i < query.size(); i++) {
if (!G[query[i]][v]) {
flag = false;
break;
}
}
if (flag)
return 0;
}
}
return 1;
}
int main() {
scanf("%d %d", &Nv, &Ne);
for (int i = 0; i < Ne; i++) {
int v1, v2;
scanf("%d %d", &v1, &v2);
G[v1][v2] = G[v2][v1] = true;
}
int M;
scanf("%d", &M);
for (int i = 0; i < M; i++) {
query.clear();
int K;
scanf("%d", &K);
for (int j = 0; j < K; j++) {
int tmp;
scanf("%d", &tmp);
query.push_back(tmp);
}
switch (judgeClique()) {
case -1: printf("Not a Clique\n"); break;
case 0: printf("Not Maximal\n"); break;
default: printf("Yes\n");
}
}
return 0;
}