HDU6152 Friend-Graph【模拟】

来源:互联网 发布:淘宝嘉年华英伦休闲鞋 编辑:程序博客网 时间:2024/06/05 07:33

题意:判断给定的点中,是否存在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");elseprintf("Great Team!\n");}}return 0;}


原创粉丝点击