HDU 6152

来源:互联网 发布:php网站数据库在哪里 编辑:程序博客网 时间:2024/06/05 04:54

题目链接: HDU 6152 - Friend-Graph

题目大意

一个团队如果有三个以上的人两两之间不是朋友或两两之间是朋友, 那这个团队是坏团队

思路

赛后才知道有这么一个定理:6个人必然有3个互相认识或者3个互不相识(组合数学,Ramsey定理)。。。书读的还是太少,吃了没文化的亏,用dfs瞎写了这么久,不过好歹AC了

dfs, u为当前节点, f为u的上一个节点, 循环遍历u的所有儿子v, 如果v和f直接有边相连, 那就存在三个人两两之间是朋友
两两直接不是朋友的就是把原来那张图反向, 用同样的方法解决

因为如果有三个以上的人两两是朋友, 这些人中任意三个人肯定也是两两互为朋友的, 所以只要找三个的就好了

五个小时的比赛神智都不清了

代码

#include <bits/stdc++.h>using namespace std;const int maxv = 3500;bool g[maxv][maxv];int V;void add_edge(int u, int v){    g[u][v] = g[v][u] = 1;}bool vist[maxv], flag;void dfs(int u, int f){    vist[u] = 1;    for(int v=1; v<=V; ++v)    {        if(g[u][v] && v!=f)        {            if(g[v][f])             {                flag = 1;                return;            }            if(!vist[v]) dfs(v, u);        }        if(flag) return;    }}int main(){    int T;    for(scanf("%d", &T); T; --T)    {        scanf("%d", &V);        memset(g, 0, sizeof(g));        for(int i=1; i<=V; ++i)        {            for(int j=1; j<=V-i; ++j)            {                int t;                scanf("%d", &t);                if(t) add_edge(i, i+j);            }        }        flag = 0;        memset(vist, 0, sizeof(vist));        for(int i=1; i<=V; ++i) if(!vist[i] && flag == 0) dfs(i, 0);        if(flag) printf("Bad Team!\n");        else         {            memset(vist, 0, sizeof(vist));            for(int i=1; i<=V; ++i)            {                for(int j=1; j<=V; ++j)                {                    if(i!=j) g[i][j] = !g[i][j];                }            }            for(int i=1; i<=V; ++i) if(!vist[i] && flag == 0) dfs(i, 0);            if(flag) printf("Bad Team!\n");            else printf("Great Team!\n");        }    }    return 0;}
原创粉丝点击