原题目: 1142 Maximal Clique (25 分).
题意
clique是一个点集,在一个无向图中,这个点集中的任意两个不同点之间都是相连的。maximal clique是一个clique,这个clique再加入一个新的结点就不是clique了。
分别给出顶点和无向边数Nv和Ne,以及每条边所连两个顶点的序号(1-Nv),
👉判断所给顶点是否构成maximal clique或者clique。
分析
- 先判断是否是clique——判断任意两顶点是否都相连。
- 再判断是否是maximal clique——遍历所有不在集合中的剩余的点,看是否满足存在一个点满足和集合中所有点相连。
- 因此,用 邻接矩阵存储存储无向图,方便查看任意两顶点间是否相连。
【注】邻接矩阵只适用于顶点数目不太大(一般不超过1000)的题目。
CODE
#include <iostream>
#include <vector>
using namespace std;
int e[210][210];
int main()
{
int nv, ne, m, ta, tb, k;
cin >> nv >> ne;
for ( int i=0; i<ne; i++ ){
cin >> ta >> tb;
e[ta][tb] = e[tb][ta] = 1; //用邻接矩阵存储无向图
}
cin >> m;
for ( int i=0; i<m; i++ ){
cin >> k;
vector<int> v(k);
int hash[210] = {0};
int isclique = 1, isMaximal = 1;
for ( int j=0; j<k; j++ ){
cin >> v[j]; //待测序列顶点
hash[v[j]] = 1; //对应顶点标记
}
//判断是否clique,即是否任意两边都相连
for ( int j=0; j<k; j++ ){
if ( isclique==0 ) break;
for ( int l=j+1; l<k; l++ ){
if ( e[v[j]][v[l]]==0 ){
isclique = 0;
printf("Not a Clique\n");
break;
}
}
}
//在是clique的条件下,才接着判断是否是maximal
if ( isclique==0 ) continue;
for ( int j=1; j<=nv; j++ ){
if ( hash[j]==0 ){ //不在待测序列中的顶点
for ( int l=0; l<k; l++){
if (e[v[l]][j]==0 ) break; //多一个点就不是clique,符合√
if ( l==k-1 ) isMaximal = 0; //满足与所有顶点相连则不是maximal
}
}
if ( isMaximal==0 ){
printf("Not Maximal\n");
break;
}
}
if ( isMaximal ) printf("Yes\n");
}
return 0;
}