目的:判断顶点子集是否可以形成一个最大的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这些,不要重名了,这是容易出错的地方。