基友,是指男性之间关系亲密的朋友。对于新一代的年轻人来说,基友也常常用在生活步调在一个节奏,或者相处好的同性身上,所以就有了新一代话语:“好基友,一辈子”“好基友,一生一起走”等说法。每逢周末,约上几个好友,喝喝小酒,吃吃鸡,男人的快乐就这么简单。现在有一个问题,一个妹子想统计男朋友的基友团有多大,需要你帮助。 什么叫基友团呢?就是圈子里的男人两两之间都是好基友。
输入格式:
第一行输入两个数,N,M,N表示总共有多少个男人,N<200,从1号开始编号,M表示总共有多个两两之间的好基友关系。 接下来的M行,每一行给出两个数字,表示这两个之间存在好基友关系。 接下来输入一个数T,表示要判断多少行, T < 100 接下来的T行,按以下方式输入:
K ID1 ID2 …… IDK
K表示基友圈里有多少个人,后面K个数据分别是基友圈里人的编号。
输出格式:
对T组查询,在一行中输出判断结论。如果是最大基友团(不包含在任何一个基友团之内的基友团),输出Yes,如果是基友团,但是不是最大,那么输出Not Maximal,如果根本不是基友团,那么输出Not a Clique
输入样例:
在这里给出一组输入。例如:
4 4
1 2
1 3
2 3
2 4
3
2 4 1
3 1 3 2
2 2 3
输出样例:
在这里给出相应的输出。例如:
Not a Clique
Yes
Not Maximal
题目:给定一个图,和一些询问,每次询问K
个点,如果是团
且不被包含在其他团内输出Yes
,
是团
且被包含则Not Max
,否则输出``no`
- 数据小,直接暴力即可
- 先判断询问点是否两两相连
O(n^2)
- 如果两两相连,则尝试找到一个
其他点S
,满足S
与所有询问点有边O(n)
1. 找到,不是最大
2. 找不到,最大
input
3 1
1 2
3
2 1 2
1 1
1 3
output
Yes
Not Maximal
Yes
input
4 5
1 2
2 3
3 4
3 1
1 4
4
3 1 2 3
2 1 3
4 1 2 3 4
1 4
output
Yes
Not Maximal
Not a Clique
Not Maximal
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
output
Yes
Yes
Yes
Yes
Not Maximal
Not a Clique
input
3 0
2
1 1
2 2 3
output
Yes
Not a Clique
c++
// #define debug
#ifdef debug
#include <time.h>
#include "win_majiao.h"
#endif
#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <math.h>
#define MAXN ((int)1e5+7)
#define ll long long int
#define INF (0x7f7f7f7f)
#define fori(lef, rig) for(int i=lef; i<=rig; i++)
#define forj(lef, rig) for(int j=lef; j<=rig; j++)
#define fork(lef, rig) for(int k=lef; k<=rig; k++)
#define QAQ (0)
using namespace std;
typedef vector<vector<int> > VVI;
#define show(x...) \
do { \
cout << "\033[31;1m " << #x << " -> "; \
err(x); \
} while (0)
void err() { cout << "\033[39;0m" << endl; }
template<typename T, typename... A>
void err(T a, A... x) { cout << a << ' '; err(x...); }
namespace FastIO{
char print_f[105];
void read() {}
void print() { putchar('\n'); }
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
x = 0;
char ch = getchar();
ll f = 1;
while (!isdigit(ch)) {
if (ch == '-') f *= -1;
ch = getchar();
}
while (isdigit(ch)) {
x = x * 10 + ch - 48;
ch = getchar();
}
x *= f;
read(oth...);
}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {
ll p3=-1;
if(x<0) putchar('-'), x=-x;
do{
print_f[++p3] = x%10 + 48;
} while(x/=10);
while(p3>=0) putchar(print_f[p3--]);
putchar(' ');
print(oth...);
}
} // namespace FastIO
using FastIO::print;
using FastIO::read;
int n, m, Q, K;
int G[256][256];
bool findit(vector<int>& arr) { //尝试找到一个点,该点和询问点都有边
bool vis[256] = { 0 };
for(auto x : arr) vis[x] = true;
for(int i=1; i<=n; i++) {
if(vis[i]) continue ;
int u = i;
bool ok = true;
for(auto v : arr) {
if(!G[u][v] || !G[v][u]) ok = false;
}
if(ok) return true;
}
return false;
}
signed main() {
#ifdef debug
freopen("test.txt", "r", stdin);
clock_t stime = clock();
#endif
read(n, m);
int u, v;
for(int i=1; i<=m; i++) {
read(u, v);
G[u][v] = G[v][u] = true;
}
read(Q);
while(Q --) {
read(K);
vector<int> arr;
while(K--) {
read(m);
arr.push_back(m);
}
bool p2p = true;
for(int i=0; i<arr.size(); i++) { //暴力判断询问点是否两两有边
// printf("%d : ", arr[i]);
for(int j=0; j<i; j++) {
u = arr[i], v = arr[j];
// printf("(%d %d) ", arr[j], G[u][v]);
p2p = p2p && (G[u][v] && G[v][u]);
}
// printf("\n");
}
if(!p2p) {
printf("Not a Clique\n");
continue ;
} else {
bool fit = findit(arr); //尝试找到与询问点都有边的点
if(fit) printf("Not Maximal\n");
else printf("Yes\n");
}
}
#ifdef debug
clock_t etime = clock();
printf("rum time: %lf 秒\n",(double) (etime-stime)/CLOCKS_PER_SEC);
#endif
return 0;
}