题意:判断给定的点中,是否存在3个以上互相无关联 或 互相有关联
思路:赛后听说有这么个定理,拉姆齐定理的通俗表述:6个人中至少存在3人相互认识或者相互不认识。那么n ≥ 6,Bad;否则,暴力判断下就好。
然而没听说过,只能走别的路了。互相有关联,就是存在一个大小为3的环(四个人相互认识,那一定有大小为3的环)。互相无关联,就是找最大独立集,二分匹配,最大独立集 = n - 最大匹配数。
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<stdlib.h>
#include<math.h>
#include<vector>
#include<list>
#include<map>
#include<stack>
#include<queue>
#include<algorithm>
#include<numeric>
#include<functional>
using namespace std;
typedef long long ll;
const int maxn = 3005;
bool line[maxn][maxn];
int vis[maxn],flag,t[maxn];
int girl[maxn],n;
vector<int> have[maxn];
void init()
{
memset(girl,-1,sizeof girl);
memset(line,false,sizeof line);
memset(vis,0,sizeof vis);
for(int i = 1; i <= n; i++)
{
have[i].clear();
}
}
int fid(int x) // 为匹配x
{
for(int j = 1; j <= n ; j++)
{
if(!vis[j] && line[x][j])
{
vis[j] = 1;
if(girl[j] == -1 || fid(girl[j]) )
{
girl[j] = x;
girl[x] = j;
return 1;
}
}
}
return 0;
}
void dfs(int x,int time)
{
if(!flag)
return;
t[x] = time;
for(int i = 1; i <= n; i++)
{
if(line[i][x])
{
if(find(have[i].begin(),have[i].end(),x)!=have[i].end()) continue;
if(t[i])
{
if( abs(time-t[i])+1 == 3)
{
flag = 0;
break;
}
have[i].push_back(x);
have[x].push_back(i);
dfs(i,t[i]);
}
else
{
have[i].push_back(x);
have[x].push_back(i);
dfs(i,time+1);
}
}
}
}
int main(void)
{
int T,k;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
init();
for(int i = 1; i < n; i++)
{
for(int j = i+1; j <= n; j++)
{
scanf("%d",&k);
if(k == 1)
line[i][j] = line[j][i] = 1;
}
}
flag = 1;
memset(t,0,sizeof t);
for(int i = 1; i <= n; i++)
{
if(!t[i])
dfs(i,1);
if(!flag)
break;
}
if(flag == 0)
printf("Bad Team!\n");
else
{
int num = 0;
for(int i = 1; i <= n; i++)
{
memset(vis,0,sizeof vis);
if(fid(i))
num++;
}
if(n-num >= 3)
flag = 0;
if(flag == 0)
printf("Bad Team!\n");
else
printf("Great Team!\n");
}
}
return 0;
}