PATa1142

it2022-05-05  181

目的:判断顶点子集是否可以形成一个最大的clique

输入:

Nv <=200 顶点数目

Ne  无向边的数目

然后Ne条边,每条边有两个顶点。

顶点从1——Nv编号

M<=100 查询数目

查询格式:

k<=Nv  k个不同顶点的序列

输出:

Yes  如果顶点的子集合可以形成一个最大的clique

Not Maximal 如果是一个clique,但不是最大的

Not a Clique 如果不是clique。

算法:

判断是不是Clique。

二重循环判断是不是每条边都存在。

再判断是不是最大的。

往里面加点,看可不可以,可以就不是最大的。

只有两百个顶点,那么就可以用邻接矩阵。

然后用一个vector存每个查询的序列,一个vector存哪些顶点在,免得添加顶

点的时候加重了。

#include<stdio.h> #include<vector> using namespace std; const int maxn = 210; int Nv,Ne; int m,k; bool g[maxn][maxn] = {false}; vector<int> query; bool isclique() { for(int i=0;i<k-1;i++) { int u = query[i]; for(int j=i+1;j<k;j++) { int v = query[j]; if(g[u][v]==false) { return false; } } } return true; } int main() { scanf("%d%d",&Nv,&Ne); for(int i=0;i<Ne;i++) { int u = 0,v = 0; scanf("%d%d",&u,&v); g[u][v] = true; g[v][u] = true; } scanf("%d",&m); for(int i=0;i<m;i++) { scanf("%d",&k); query.clear(); vector<int> a(maxn,0); for(int j=0;j<k;j++) { int x; scanf("%d",&x); query.push_back(x); a[x] = 1; } if(isclique()==false) { printf("Not a Clique\n"); }else{ int tag = 0; for(int j=1;j<=Nv;j++) { int u = j; if(a[j]==0) { int flag = 0; for(int l=0;l<k;l++) { int v = query[l]; if(g[u][v]==false) { flag = 1; break; } } if(flag==0) { tag = 1; break; } } } if(tag==1) { printf("Not Maximal\n"); }else { printf("Yes\n"); } } } return 0; }

反思:是内容还是下标,容易弄混,要清晰一点。ijk这些,不要重名了,这是容易出错的地方。


最新回复(0)