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


#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
");
        }else if(isClque == 1){
            printf("Not Maximal
");
        }else{
            printf("Not a Clique
");
        }
    }
    cin >> M;
    return 0;
}
View Code

总结:

1、题意:给出一个点的集合,判断这些点是否是给出的无向图的极大团。根据题意,极大团是一个点的集合:这个集合中的任意两个点之间都存在一条边,且点的个数是极大的。

2、由于给出的节点数N较少,直接暴力循环即可。对每一个待判断集合中的点,都验证它是否与集合中其它点相连接即可。极大性验证:依次检验非集合内的点,如果存在一个点v与集合内的点都连接,则不是极大团。

原文地址:https://www.cnblogs.com/zhuqiwei-blog/p/9566681.html