1

题目大意:

给定一个无向图G,顶点编号为1到Nv,Ne条边,判断给出的一组顶点集合是否构成该图的一个极大完全子图,如果是输出Yes,否则判断是否是一个完全子图,如果是输出Not Maximal,否则输出Not a Clique。

算法思路:

首先得判断输入的集合是否是当前图G的一个完全子图,这里采用isClique函数来实现,如果是就再判断是否是一个极大完全子图,这里采用isMaximal来实现,最后就根据判断的结果进行相应的输出就好。

isClique函数:

直接遍历输入集合的不同顶点之间是否存在不邻接的点,如果是就返回false,否则返回true。

bool G[201][201];// 邻接矩阵,判断2点是否邻接 
bool isClique(const vector<int> &a){
    for(int i:a){
        for(int j:a){
            if(i!=j&&!G[i][j]){
                // 存在不邻接的结点 
                return false;
            }
        }
    }
    return true;
}
isMaximal函数:

我们使用exist标记所有输入的结点,然后遍历所有的顶点,只要没有出现在输入集合中并且与集合所有顶点都邻接,说明不是极大完全子图,返回false,否则返回true。

bool G[201][201];// 邻接矩阵,判断2点是否邻接 
bool exist[201];// 标记每一个在subset中的结点编号 
bool isMaximal(const vector<int> &a,int N){
    for(int i=1;i<=N;++i){
        if(exist[i]) continue;
        bool isAllAdjcent = true;
        for(int j:a){
            // 得判断i和所有的点是否邻接
            if(!G[i][j]){
                isAllAdjcent = false;
                break;
            }
        }
        if(isAllAdjcent){
            // 可以扩展一个邻接点 
            return false;
        }
    }
    return true;
}

提交结果:

image.png

AC代码:

#include<cstdio>
#include<vector>
#include<cstring>

using namespace std;

bool G[201][201];// 邻接矩阵,判断2点是否邻接 
bool exist[201];// 标记每一个在subset中的结点编号 
 
bool isClique(const vector<int> &a){
    for(int i:a){
        for(int j:a){
            if(i!=j&&!G[i][j]){
                // 存在不邻接的结点 
                return false;
            }
        }
    }
    return true;
}

bool isMaximal(const vector<int> &a,int N){
    for(int i=1;i<=N;++i){
        if(exist[i]) continue;
        bool isAllAdjcent = true;
        for(int j:a){
            // 得判断i和所有的点是否邻接
            if(!G[i][j]){
                isAllAdjcent = false;
                break;
            }
        }
        if(isAllAdjcent){
            // 可以扩展一个邻接点 
            return false;
        }
    }
    return true;
}

int main(){
    int Nv,Ne;
    scanf("%d %d",&Nv,&Ne);
    int a,b;
    for(int i=0;i<Ne;++i){
        scanf("%d %d",&a,&b);
        G[a][b] = G[b][a] = true;
    }
    int M,N;
    scanf("%d",&M);
    for(int i=0;i<M;++i){
        vector<int> subset;
        memset(exist,0,sizeof(exist));
        scanf("%d",&N);
        for(int j=0;j<N;++j){
            scanf("%d",&a);
            exist[a] = true;
            subset.push_back(a);
        }
        if(!isClique(subset)){
            printf("Not a Clique\n");
        }else if(!isMaximal(subset,Nv)) {
            printf("Not Maximal\n");
        }else {
            printf("Yes\n");
        }
    }
    return 0;
} 

乔梓鑫
569 声望17 粉丝

主要分享个人学习经验和心得