Frogs' Neighborhood POJ

来源:互联网 发布:电路热仿真软件 编辑:程序博客网 时间:2024/06/07 00:56

havel定理:判断度数序列是否可图(简单图)

题意
未名湖附近共有N个大小湖泊L1, L2, …, Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤i ≤ N)。如果湖泊Li和Lj之间有水路相连(无向图),则青蛙Fi和Fj互称为邻居。现在已知每只青蛙的邻居数目x1,x2, …, xn,请你给出每两个湖泊之间的相连关系。
思路
直接贪心是有误的:1 2 3 2 0
用 havel定理
判定过程:
(1)对当前数列排序,使其呈递减,
(2)从S【2】开始对其后S【1】个数字-1,
(3) 一直循环直到当前序列出现负数(即不是可图的情况)或者当前序列全为0 (可图)时退出。
代码

/* * Author       :  Echo * Email        :  1666424499@qq.com   * Description  :    * Created Time :  2017/10/15 16:40:58 * Last Modify  :  2017/10/15 17:33:16 * File Name    :  write.cpp */#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <string>using namespace std;const int maxn=20;const int maxm=1e4+100;const int INF=1e9;int n;struct node{    int cnt,id;}an[maxn];int mp[maxn][maxn];bool cmp(node a,node b){    return a.cnt>b.cnt;}int main(){    int t;    cin>>t;    while(t--){        cin>>n;        for(int i=1;i<=n;i++){            scanf("%d",&an[i].cnt);            an[i].id=i;        }        memset(mp,0,sizeof(mp));        int flg=1;        while(1){            sort(an+1,an+n+1,cmp);            if(an[1].cnt==0)break;            for(int i=2;i<=n;i++){                if(an[1].cnt==0)break;                an[1].cnt--;                an[i].cnt--;                mp[an[1].id][an[i].id]=mp[an[i].id][an[1].id]=1;                if(an[i].cnt<0){                    flg=0;                    break;                }            }            if(flg==0)break;        }        if(flg==0){            printf("NO\n\n");            continue;        }        printf("YES\n");        for(int i=1;i<=n;i++){            for(int j=1;j<=n;j++){                printf("%d%c",mp[i][j],j==n? '\n':' ');            }        }        printf("\n");    }    return 0;}