A clique is a subset of vertices of an undirected graph such that every two distinct vertices in the clique are adjacent. A maximal clique is a clique that cannot be extended by including one more adjacent vertex.
Now it is your job to judge if a given subset of vertices can form a maximal clique.
Input Specification:
Each input file contains one test case. For each case, the first line gives two positive integers Nv (≤ 200), the number of vertices in the graph, and Ne, the number of undirected edges. Then Ne lines follow, each gives a pair of vertices of an edge. The vertices are numbered from 1 to Nv.
After the graph, there is another positive integer M (≤ 100). Then M lines of query follow, each first gives a positive number K (≤ Nv), then followed by a sequence of K distinct vertices. All the numbers in a line are separated by a space.
Output Specification:
For each of the M queries, print in a line Yes if the given subset of vertices can form a maximal clique; or if it is a clique but not a maximal clique, print Not Maximal; or if it is not a clique at all, print Not a Clique.
Sample Input:
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
Sample Output:
Yes
Yes
Yes
Yes
Not Maximal
Not a Clique
题目大意
clique:一个点集中,每对顶点都是邻接的。maximal clique:无法再扩展其他顶点的clique。试判断给出的点集是否能形成maximal clique。
思路
由于数据规模不大,可采用暴力的方法,先将图用邻接矩阵表示,将点集用vector存储。遍历点集,判断每个顶点是否与其他所有顶点都相邻(邻接矩阵的值是否为1),若是,则为clique,此时可进一步判断其是否为maximal clique:遍历该图中其他顶点,判断是否存在与点集中所有顶点全部相邻的点,若没有,则是maximal clique。
AC代码
#include <cstdio>
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 210;
int G[maxn][maxn] = {0}; //邻接矩阵
bool vis[maxn]; //是否存在于点集中
int Nv, Ne, m, k;
int main(){
scanf("%d%d", &Nv, &Ne);
int u, v;
for(int i = 0; i < Ne; i++){
scanf("%d%d", &u, &v);
G[u][v] = G[v][u] = 1;
}
scanf("%d", &m);
for(int i = 0; i < m; i++){
scanf("%d", &k);
vector<int> subset(k); //点集
fill(vis, vis + maxn, false);
for(int j = 0; j < k; j++){
scanf("%d", &subset[j]);
vis[subset[j]] = true;
}
bool isClique = true; //判断是否为Clique
for(int j = 0; j < k; j++){
for(int t = j + 1; t < k; t++){
if(G[subset[t]][subset[j]] == 0)
isClique = false;
break;
}
if(!isClique) break;
}
if(isClique){ //进一步判断是否为maximal clique
bool isMaxClique = true;
for(int j = 1; j <= Nv; j++){
if(vis[j] == false){ //该点集以外的顶点
bool flag = true; //是否与点集中所有顶点均相邻
for(auto it = subset.begin(); it != subset.end(); it++){
if(G[*it][j] == 0){
flag = false;
break;
}
}
if(flag == true){
isMaxClique = false;
break;
}
}
}
if(isMaxClique) printf("Yes\n");
else printf("Not Maximal\n");
}
else printf("Not a Clique\n");
}
return 0;
}