17年秋季第三题 PAT甲级 1142 Maximal Clique (25分)

汇总贴

2020年3月PAT甲级满分必备刷题技巧

题目

来源:https://pintia.cn/problem-sets/994805342720868352/problems/994805343979159552

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. (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

概念解释

1.clique 团
无向图中,两两之间有边的顶点集合。

2.maximal clique 极大团
是一个团,该团不能被更大的团所包含,换句话说,再也不存在一个点与该团中的任意顶点之间存在一条边。

题目分析

给出无向图,判断是极大团、团或不是团。用反证法的思路去想最快,否定是团或者极大团是很简单的,如果都否定不了就是极大团。

满分代码

#include<iostream>
using namespace std;
const int maxn=205;
int G[maxn][maxn];
int a[maxn],b[maxn];
int main(){
    int n,m,k,l,u,v;
    cin>>n>>m;
    fill(G[0],G[0]+maxn*maxn,0);
    for(int i=0;i<m;i++){
        cin>>u>>v;
        G[u][v]=G[v][u]=1;
    }
    cin>>k;
    for(int i=0;i<k;i++){
        cin>>l;
        fill(a,a+maxn,0);
        fill(b,b+maxn,0);
        for(int j=0;j<l;j++){
            cin>>u;
            a[u]=1;//为了判断是不是有点是孤立的
            b[j]=u;//要判断的团顶点序号
        }
        int maxc=0,cliq=1;
        //判断是不是团
        for(int j=0;j<l-1;j++){
            for(int p=j+1;p<l;p++){
                if(G[b[j]][b[p]]==0){
                    cliq=0;
                }
            }
        }
        if(cliq==0){
            cout<<"Not a Clique"<<endl;
            continue;
        }
        //判断是不是极大团
        for(int p=1;p<=n;p++){
            for(int j=0;j<l;j++){
                if(a[p]==0 && G[b[j]][p]==1){
                    maxc++;
                }
            }
            if(maxc==l){
                break;
            }else{
                maxc=0;
            }
        }
        if(maxc==l){
            cout<<"Not Maximal"<<endl;
        }else{
            cout<<"Yes"<<endl;
        }
        
    }
    return 0;
}


猜你喜欢

转载自blog.csdn.net/allisonshing/article/details/104472391