POJ 1659 Frogs' Neighborhood【Havel算法】

题意: 告诉你有 N 湖是,并告诉你和每个湖相连湖的个数,问你能否找到一种可能的连通方式。

分析: 问题的目的就是看看能否重建这个连通图,可以用Havel算法

Havel算法的思想简单的说如下:

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

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

(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,能构成图,跳出!

View Code
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
    int xu,num;
}q[12];
int g[12][12];
int cmp(const void*p1,const void*p2)
{
    struct node* c=(node*)p1;
    struct node* d=(node*)p2;
    return d->num-c->num;
}
int main()
{
    int t,i,j,n,flag;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        flag=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&q[i].num);
            q[i].xu=i;
        }
        memset(g,0,sizeof(g));
        while(1)
        {
            qsort(q+1,n,sizeof(q[0]),cmp);
            if(q[1].num==0)break;
            for(i=1;i<=q[1].num;i++)
            {
                q[1+i].num-=1;
                g[q[1].xu][q[1+i].xu]=g[q[1+i].xu][q[1].xu]=1;
                if(q[1+i].num<0)
                {
                    flag=1;
                    goto loop;
                }
            }
            q[1].num=0;
        }
loop:    if(flag)
        printf("NO\n");
        else {
            printf("YES\n");
            for(i=1;i<=n;i++)
                for(j=1;j<=n;j++)
                    printf("%d%c",g[i][j],j==n?'\n':' ');
        }
        printf("\n");
    }
    return 0;
}

 

 

posted @ 2012-04-30 17:16  'wind  阅读(332)  评论(0编辑  收藏  举报