Friend-Graph
HDU - 6152
题意:给你n个人,告诉你他们之间的关系。如果有三个以上的人互相不认识或者互相认识,就认为这个团队是“Bad Team”,反之输出“Great Team”。
我的想法就是暴力搜索,用一个二维数组保存每个人之间的关系,再三重循环看是否有三个人关系都为1,或者都为0,则是"Bad Team!"反之就是"Great Team"。不过这样好像时间花费会很久,网上说什么拉姆齐二染色定理?emmmm我也不懂
记得要用bool型建数组,不然会爆内存!
#include<iostream>
using namespace std;
bool a[3000][3000];
int main()
{
int T;
cin >> T;
while (T--) {
int n, flag = 0;
cin >> n;
for (int i = 1; i < n; i++) {
for (int j = i + 1; j <= n; j++) {
cin >> a[i][j];
a[j][i] = a[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (i == j)
continue;
for (int k = 1; k <= n; k++) {
if (i == k || j == k)
continue;
if (a[i][j] && a[i][k] && a[k][j]) {
flag = 1; break;
}
if (!a[i][j] && !a[i][k] && !a[k][j]) {
flag = 1; break;
}
}
if (flag == 1)
break;
}
if (flag == 1)
break;
}
if (flag == 1)
cout << "Bad Team!" << endl;
else
cout << "Great Team!" << endl;
}
return 0;
}
拉姆齐Ramsey定理是一个稍微难于理解的定理,该定理又称拉姆齐二染色定理,是要解决这样的问题:
要找这样一个最小的数 R(k,l)=n,使得 n 个人中必定有 k 个人相识或 l 个人互不相识。
比如本题中的R(3,3) = 6,有3个人认识或者3个人互不认识,最小的数是6个人。
6个人中必有3个人相互认识或者相互不认识。
证明并不难,采用二染色方法比较直观的来看看吧。
对于一个有向图G,有6个节点,边只有蓝色或者红色。
假定G是一个完全图,我们选取一个节点1,它有5条边与其他节点相连。如下图:
根据我们之前学过的鸽巢原理,5条边中至少有3条是同一种颜色。
对于节点3、4、5,他们之间有3条边。
注意这3条边如果有一条是红色,比如3-5。
那么1-3-5就构成了一个红色三角形。
如果这3条边全是蓝色,那么3-4-5构成了一个蓝色三角形。
于是拉姆齐定理就这样被证明了。不管这6个节点之间的边是什么颜色(蓝色表示认识,红色表示不认识),都会不可避免的构成一个三边是同色的三角形。而这个三角形正好表示有3个人认识或者3个人互不认识。
#include <bits/stdc++.h>
using namespace std;
bool G[6][6];
int main()
{
int T;
scanf("%d", &T);
//用例次数
while ( T-- )
{
int n;
scanf("%d", &n);
//输入n-1行
for ( int i = 1; i <= n; i++ )
{
for ( int j = i + 1; j <= n; j++ )
{
int e;
scanf("%d", &e);
//设置关系
if ( n <= 6 )
G[j][i] = G[i][j] = e;
}
}
//如果只有1、2个人,则肯定是好团队(要么认识、要么不认识)
if (n < 3)
{
printf("Great Team!\n");
continue;
}
//如果大于6个人,则肯定是不好的团队,根据拉姆齐定理: 6 个人中至少存在3人相互认识或者相互不认识。
if (n >= 6)
{
printf("Bad Team!\n");
continue;
}
//暴力搜索(量级非常小)
bool flag = false;
for ( int a = 1; a <= n; a++ )
for ( int b = a + 1; b <= n; b++ )
for ( int c = b + 1; c <= n; c++ )
if ( (G[a][b] && G[a][c] && G[b][c])
||(!G[a][b] && !G[a][c] && !G[b][c]) )
flag = true;
if ( flag ) printf("Bad Team!\n");
else printf("Great Team!\n");
}
return 0;
}