Friend-Graph HDU - 6152 签到题 暴力遍历

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;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值