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
 
 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <map>
 5 #include <string>
 6 #include <vector>
 7 #include <set>
 8 #include <cctype>
 9 using namespace std;
10 const int maxn=210;
11 int n,m,k;
12 set<int> adj[maxn];
13 int g[maxn][maxn];
14 int main(){
15     fill(g[0],g[0]+maxn*maxn,0);
16     scanf("%d %d",&n,&m);
17     for(int i=0;i<m;i++){
18         int c1,c2;
19         scanf("%d %d",&c1,&c2);
20         g[c1][c2]=1;
21         g[c2][c1]=1;
22         adj[c1].insert(c2);
23         adj[c2].insert(c1);
24     }
25     scanf("%d",&k);
26     for(int i=0;i<k;i++){
27         int x;
28         scanf("%d",&x);
29         int que[maxn]={0};
30         int vis[maxn]={0};
31         for(int j=0;j<x;j++){
32             int tmp;
33             scanf("%d",&tmp);
34             que[j]=tmp;
35             vis[tmp]=1;
36         }
37         int flag=0;
38         for(int j=0;j<x;j++){
39             if(flag==0){
40                 for(int q=j+1;q<x;q++){
41                     if(g[que[j]][que[q]]==0){
42                         flag=1;
43                         printf("Not a Clique\n");
44                         break;
45                     }
46                 }
47             }
48             else break;
49         }
50         if(flag==0){
51             int flag1=0,flag2=0;
52             for(int j=1;j<=n;j++){
53                 flag2=0;
54                 if(vis[j]==1) continue;
55                 for(int q=0;q<x;q++){
56                     if(g[que[q]][j]==0){
57                         flag2=1;
58                         break;
59                     }
60                 }
61                 if(flag2==0){
62                     flag1=1;
63                     printf("Not Maximal\n");
64                     break;
65                 }
66             }
67             if(flag1==0)printf("Yes\n");
68         }
69     }
70 }
View Code

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

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