hdu 2454 Degree Sequence of Graph G(Havel-Hakimi算法)

Degree Sequence of Graph G

分析

  • 度序列:若把图 G 所有顶点的度数排成一个序列 d,则称 d 为图 G 的度序列
  • 简单图:无平行边、无自环(ring)【定义
  • 可图化:给定一个非负整数序列d={d1,d2,…dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化;
  • 可简单图化:给定的度序列若可以对应一个简单图,则称此序列可简单图化;
  • 可图化判定: (d1+d2+…+dn)%2 = 0。 构造方法:简单地把奇数度的点配对,其它自环;
  • 可简单图化判定: 把序列排成不增序(d1 >= d2 >= … >= dn),则d可简单图化当且仅当d={d2-1, d3-1, …, dd1+1-1, dd1+2, …, dn}可简单图化。【判定定理】
  • Havel-Hakimi算法
    1)该算法是基于可简单图化判定定理的
    2)算法:d排序,找出度最大的顶点(设度为d1),使它和度次大的d1个点之间有边相连;然后递归处理余下的n-1个顶点,直到构造出完整的图,或出现负度等明显不合理的情况。
    3)算法正确性证明:
    (a)如果按算法构造出一个简单图,则说明此度序列可简单图化;
    (b)如果按算法构造简单图失败,是否意味着按其它算法也一定构造不出简单图呢?答:是的,一定构造不出简单图。此结论可通过逆否命题间接证明。也就是说,如果某度序列存在一个对应的简单图,那么按Havel-Hakimi算法必可以构造出一个简单图。证明如下:
    设度d1、d2、d3、…、dn对应的顶点分别为V1、V2、V3、…、Vn
  • 若对应的简单图符合Havel-Hakimi算法,即:d的前d1大的度对应的顶点与顶点V1都有边,则得证;
  • 若对应的简单图不符合Havel-Hakimi算法,即:存在顶点Vi,Vi与顶点V1间无边但Vi的度在序列的前d1大的度中;同时,存在Vj与V1有边但顶点Vj度不在序列的前d1大的度中。因di>= dj,故必存在Vk,Vk与Vi间有边,而与Vj间无边,因此去除V1Vk、ViVk两条边,并添加V1Vi、VjVk两条边,各顶点的度不变,简单图性质不变。只要当前简单图不符合算法,继续上述操作,直到符合算法。因此得证。
  • 贪心的观点:因为度越大,越不容易可简单图化,所以先判断度大的点。

代码

#include<bits/stdc++.h>
using namespace std;
int a[10010];
int main(){
	int T, n, tot, ans;
	scanf("%d", &T);
	while(T--){
		scanf("%d", &n);
        tot = 0;
		for(int i = 1; i <= n; i++) scanf("%d", a+i), tot += a[i];
        if(tot&1) { // 可图化判定
            printf("no\n");
            continue;
        }
        // 可简单图化判定
        for(int i = 1; i <= n; i++){
            sort(a+i, a+n+1, [](int x, int y){return x > y;});
            int m = a[i];
            if(m < 0 || m > n-i) break;
            a[i] = 0;
            for(int j = 1; j <= m; j++) a[i+j]--;
        }
        ans = 1;
        for(int i = 1; i <= n && ans; i++){
            if(a[i]) ans = 0;
        }
		printf("%s\n", ans?"yes":"no");
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jpphy0

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值