目的:判斷頂點子集是否可以形成一個最大的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這些,不要重名了,這是容易出錯的地方。