POJ 1659 (Havel-Hakimi定理,度序列 还原无向图)

题目链接:http://poj.org/problem?id=1659

题意: 中文题目,不用说了吧。

思路:  havel算法的应用:

(1)对序列从大到小进行排序。

(2)设最大的度数为 t ,把最大度数后(不包括自己)的 t 个度数分别减1,然后最大的度数置0(意思就是把度数最大的点与后几个点进行连接)

(3)如果序列中出现了负数,证明无法构成。如果序列全部变为0,证明能构成,跳出循环。前两点不出现,就跳回第一步!

简单例子:

4 4 3 3 2 2

第二步后0 3 2 2 1 2

排完续后3 2 2 2 1 0

第二步后0 1 1 1 1 0

排完续后1 1 1 1 0 0

第二步后0 0 1 1 0 0

排完续后1 1 0 0 0 0

第二步后0 0 0 0 0 0

全为0,能构成图,跳出!

AC代码:

#include<cstdio>
#include<stack>
#include<cstring>
#include<algorithm>
using namespace std;

struct node{
    int d,id;
}s[15];

int mp[15][15];

bool cmp(node A,node B){
    return A.d > B.d;
}

int main() {
    int t; scanf("%d",&t);
    while(t --){
        memset(mp,0,sizeof(mp));
        int n; scanf("%d",&n);
        for(int i = 1;i <= n;i ++){
            scanf("%d",&s[i].d);
            s[i].id = i;
        }
        int flag = 1;
        while(1){
            sort(s + 1,s + 1 + n,cmp);
            if(s[1].d == 0) break;
            for(int i = 2;i <= 1 + s[1].d;i ++){
                s[i].d --;
                if(s[i].d < 0){ flag = 0; break; }
                mp[s[1].id][s[i].id] = mp[s[i].id][s[1].id] = 1;    //构图, 很明显 无向图是对称矩阵
            }
            s[1].d = 0;
            if(!flag) break;
        }
        if(!flag) printf("NO\n");
        else {
            printf("YES\n");
            for(int i = 1;i <= n;i ++,printf("\n"))
                for(int j = 1;j <= n;j ++)
                    printf("%d ",mp[i][j]);
        }
        printf("\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/no_O_ac/article/details/81368390
今日推荐