A1142. Maximal Clique
A clique is a subset of vertices of an undirected graph such that every two distinct vertices in the clique are adjacent. A maximal cliqueis a clique that cannot be extended by including one more adjacent vertex. (Quoted from https://en.wikipedia.org/wiki/Clique_(graph_theory))
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
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<algorithm> #include<cstdio> using namespace std; int G[500][500] = {0}; int Nv, Ne; int seq[500], hashTB[500]; 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] = 1; } int M; scanf("%d", &M); for(int i = 0; i < M; i++){ fill(hashTB, hashTB + 500, 0); int K; scanf("%d", &K); for(int j = 0; j < K; j++){ scanf("%d", &seq[j]); hashTB[seq[j]] = 1; } int isClque = 1; for(int j = 0; j < K; j++){ for(int m = j + 1; m < K; m++){ if(G[seq[j]][seq[m]] == 0){ isClque = 0; break; } if(isClque == 0) break; } } int isMax = 1; for(int n = 1; n <= Nv; n++){ if(hashTB[n] == 0){ int tag = 1; for(int p = 0; p < K; p++){ if(G[seq[p]][n] == 0){ tag = 0; break; } } if(tag == 1){ isMax = 0; break; } } } if(isMax == 1 && isClque == 1){ printf("Yes\n"); }else if(isClque == 1){ printf("Not Maximal\n"); }else{ printf("Not a Clique\n"); } } cin >> M; return 0; }
总结:
1、题意:给出一个点的集合,判断这些点是否是给出的无向图的极大团。根据题意,极大团是一个点的集合:这个集合中的任意两个点之间都存在一条边,且点的个数是极大的。
2、由于给出的节点数N较少,直接暴力循环即可。对每一个待判断集合中的点,都验证它是否与集合中其它点相连接即可。极大性验证:依次检验非集合内的点,如果存在一个点v与集合内的点都连接,则不是极大团。