POJ 1659 Frogs' Neighborhood (Havel定理构造图)

题意:根据图的度数列构造图

分析:该题可根据Havel定理来构造图。Havel定理对可图化的判定:

  把序列排成不增序,即d1>=d2>=……>=dn,则d可简单图化当且仅当d’={d2-1,d3-1,……d(d1+1)-1, d(d1+2),d(d1+3),……dn}可简单图化。简单的说,把d排序后,找出度最大的点(设度为d1),把它与度次大的d1个点之间连边,然后这个点就可以不管了,一直继续这个过程,直到建出完整的图,或出现负度等明显不合理的情况。

 

#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn =20;
int G[maxn][maxn];
struct Node{
    int d,id;
    bool operator <(const Node &rhs)const{return d>rhs.d;} 
}p[maxn];

int main(){
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int T,N,M,u,v,tmp;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N);
        memset(G,0,sizeof(G));
        for(int i=1;i<=N;++i){
            scanf("%d",&p[i].d);
            p[i].id = i;
        } 
        bool flag = true;
        while(true){
            sort(p+1,p+N+1);
            if(!p[1].d) break;
            int u = p[1].id;
            for(int j=2;p[1].d &&j<=N;++j){
                int v =p[j].id;
                if(!p[j].d) continue;
                G[u][v] = G[v][u] = 1;
                p[1].d--;
                p[j].d--;
            }
            if(p[1].d>0){
                flag = false;
                break;
            }
        }
        if(!flag) printf("NO\n");
        else{
            printf("YES\n");
            for(int i=1;i<=N;++i){
                for(int j=1;j<=N;++j){
                    printf("%d ",G[i][j]);
                }
                printf("\n");
            }
        }
        printf("\n");
    }
    return 0;
}

 

posted @ 2018-07-25 11:55  xiuwenL  阅读(179)  评论(0编辑  收藏  举报