题目大意:
给定一个无向图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;
}
提交结果:
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;
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。