PAT A1142 Maximal Clique (25 分)——图

时间:2023-03-09 03:18:36
PAT A1142 Maximal Clique (25 分)——图

A clique is a subset of vertices of an undirected graph such that every two distinct vertices in the clique are adjacent. A maximal clique is a clique that cannot be extended by including one more adjacent vertex. (Quoted from https://en.wikipedia.org/wiki/Clique_(graph_theory))

Now it is your job to judge if a given subset of vertices can form a maximal clique.

Input Specification:

Each input file contains one test case. For each case, the first line gives two positive integers Nv (≤ 200), the number of vertices in the graph, and Ne, the number of undirected edges. Then Ne lines follow, each gives a pair of vertices of an edge. The vertices are numbered from 1 to Nv.

After the graph, there is another positive integer M (≤ 100). Then M lines of query follow, each first gives a positive number K (≤ Nv), then followed by a sequence of K distinct vertices. All the numbers in a line are separated by a space.

Output Specification:

For each of the M queries, print in a line Yes if the given subset of vertices can form a maximal clique; or if it is a clique but not a maximal clique, print Not Maximal; or if it is not a clique at all, print Not a Clique.

Sample Input:

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

Sample Output:

Yes
Yes
Yes
Yes
Not Maximal
Not a Clique
 #include <stdio.h>
#include <algorithm>
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <set>
#include <cctype>
using namespace std;
const int maxn=;
int n,m,k;
set<int> adj[maxn];
int g[maxn][maxn];
int main(){
fill(g[],g[]+maxn*maxn,);
scanf("%d %d",&n,&m);
for(int i=;i<m;i++){
int c1,c2;
scanf("%d %d",&c1,&c2);
g[c1][c2]=;
g[c2][c1]=;
adj[c1].insert(c2);
adj[c2].insert(c1);
}
scanf("%d",&k);
for(int i=;i<k;i++){
int x;
scanf("%d",&x);
int que[maxn]={};
int vis[maxn]={};
for(int j=;j<x;j++){
int tmp;
scanf("%d",&tmp);
que[j]=tmp;
vis[tmp]=;
}
int flag=;
for(int j=;j<x;j++){
if(flag==){
for(int q=j+;q<x;q++){
if(g[que[j]][que[q]]==){
flag=;
printf("Not a Clique\n");
break;
}
}
}
else break;
}
if(flag==){
int flag1=,flag2=;
for(int j=;j<=n;j++){
flag2=;
if(vis[j]==) continue;
for(int q=;q<x;q++){
if(g[que[q]][j]==){
flag2=;
break;
}
}
if(flag2==){
flag1=;
printf("Not Maximal\n");
break;
}
}
if(flag1==)printf("Yes\n");
}
}
}

注意点:题目意思就是找一个团,里面每个元素之间都两两相连,如果没有另外的点可以加进去后还满足这个条件就是最大团。一开始一直在想把给定序列的元素每个遍历,找到每个元素相连的元素,再去对他们做交集,看看和给定序列一不一样。做交集这个就很麻烦了,看了大佬的思路,原来不用纠结在给定的点上,要看另外的点能不能加进来,其实就是题目里给的意思,我自己转弯了。

这种多个判断的题已经不是第一次做到了,类似的还有1150 Travelling Salesman Problem (25 分),也是和图有关,判断各种东西