POJ:1659 Frogs' Neighborhood (Havel-Hakimi定理)

本文介绍如何使用Havel-Hakimi定理来判断一个非负整数序列是否可以形成一个图,并提供了一个C++实现的例子。通过排序、递减度数并检查序列是否满足可图条件,我们可以验证序列的图属性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

序列是可图的:一个非负整数组成的有限序列如果是某个无向图的度序列,则称该序列是可图的。


判定一个序列是否是可图的,有以下Havel-Hakimi定理。

 

Havel—Hakimi定理:由非负数组成的非增序列s:d1,d2,···,dn(n>=2,d1>=1)是可图的,当仅当序列s1:d2-1,d3-1,···,dd1+1 -1,dd1+2,····,dn是可图的。

序列s1中有n-1个非负数,s序列中d1后的前d1个度数减1后构成s1中的前d1个数。

 

判定过程:

(1)对当前数列排序,使其呈递减

(2)从S【2】开始对其后S【1】个数字-1

(3)一直循环直到当前序列出现负数或者最大度数超过了剩下的顶点数(即不是可图的情况)、当前序列全为0 (可图)时退出

 

Havel-Hakimi定理说简单点就是给你每个顶点的度数,看它们能不能构成图。

 

 

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct Elem
{
    int num,cou;
};
bool cmp (Elem a,Elem b)
{
    return a.cou>b.cou;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        Elem p[15];
        scanf("%d",&n);
        for(int i=1; i<=n; ++i)
        {
            scanf("%d",&p[i].cou);
            p[i].num=i;
        }
        int Mat[12][12]= {0};
        int pos=1;
        sort(p+1,p+n+1,cmp);
        bool ok=true;
        while(p[pos].cou&&ok)
        {
            if(p[pos].cou>n-pos)
            {
                ok=false;
                break;
            }
            else
            {
                for(int i=1; i<=p[pos].cou&&ok; ++i)
                {
                    p[pos+i].cou--;
                    if(p[pos+i].cou<0)
                    {
                        ok=false;
                        break;
                    }
                    int x=p[pos].num,y=p[pos+i].num;
                    Mat[x][y]=Mat[y][x]=1;
                }
                pos++;
                if(ok) sort(p+pos,p+n+1,cmp);
            }
        }
        if(!ok)
            printf("NO\n");
        else
        {
            printf("YES\n");
            for(int i=1; i<=n; ++i)
            {
                for(int j=1; j<=n; ++j)
                    if(j==1) printf("%d",Mat[i][j]);
                    else printf(" %d",Mat[i][j]);
                printf("\n");
            }
        }
        if(T)printf("\n");
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值