PAT_A1142
PAT甲级1142.
目录
A1142
题目
样例
输入:
8 10
5 6
7 8
6 4
3 6
4 5
2 3
8 2
2 7
5 3
3 4
6
4 5 4 3 6
3 2 8 7
2 2 3
1 1
3 4 3 6
3 3 2 1
输出:
Yes
Yes
Yes
Yes
Not Maximal
Not a Clique
思路和坑点
思路:
首先明确概念:clique
指的是图的某一个顶点的子集中,任意两个顶点之间都相互邻接。maximal clique
指的是clique
的最大集合,不能再找到一个顶点加入maximal clique
以满足clique
的要求。
由此,可以得到思路,默认是clique
,当发现有不邻接的定点对儿时,则不是一个clique
,然后再判断是不是maxiaml
,判断是否存在一个不在集合中的点,满足和当前集合中所有顶点都邻接,如果能找到则不是maximal
。
AC代码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 205
int G[MAXN][MAXN]={0};
int n,m;
void Judge();
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif
int a,b,k;
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++){
scanf("%d%d",&a,&b);
G[a][b]=G[b][a]=1;
}
scanf("%d",&k);
for(int i=0;i<k;i++)
Judge();
return 0;
}
void Judge()
{
int flag=0; //0表示yes,1表示not max,2表示not clique
vector<bool> vis(n);
fill(vis.begin(),vis.end(),false);//所有的顶点的访问标记
int num;
scanf("%d",&num);
vector<int> vn(num); //读入一组结点
for(int i=0;i<num;i++){
scanf("%d",&vn[i]);
vis[vn[i]]=true;
}
for(int i=0;i<num;i++){ //如果出现两个顶点之间不连通便是2
for(int j=i+1;j<num;j++){
if(G[vn[i]][vn[j]]==0){
flag=2;
break;
}
}
if(flag==2) break;
}
if(flag==0){ //如果不是2,则继续判别
for(int i=1;i<=n;i++){
int cnt=0; //计数器
if(vis[i]==false){ //检测不在当前集合中的的顶点
for(int j=0;j<vn.size();j++)
if(G[i][vn[j]]==1) cnt++; //统计结点i和当前集合中的链接个数
if(cnt==vn.size()){ //如果结点i能够和当前集合中所有结点想邻接,则说明当前集合可以扩充,不是max,标记为1
flag=1; break;
}
}
}
}
switch(flag){ //根据标记输出类型
case 0:puts("Yes");break;
case 1:puts("Not Maximal");break;
case 2:puts("Not a Clique");break;
default: break;
}
}