Havel定理 10720 - Graph Construction&&POJ 1659

本文介绍图论中可图化与可简单图化的概念及其判定方法,详细解析Havel-Hakimi定理的应用,并通过示例说明如何确定一个序列是否能构成有效的无向图。

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

给定一个非负整数序列{dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化。进一步,若图为简单图,则称此序列可简单图化
可图化的判定:d1+d2+……dn=0(mod 2)。关于具体图的构造,我们可以简单地把奇数度的点配对,剩下的全部搞成自环。
可简单图化的判定(Havel定理):把序列排成不增序,即d1>=d2>=……>=dn,则d可简单图化当且仅当d’={d2-1,d3-1,……d(d1+1)-1, d(d1+2),d(d1+3),……dn}可简单图化。简单的说,把d排序后,找出度最大的点(设度为d1),把它与度次大的d1个点之间连边,然后这个点就可以不管了,一直继续这个过程,直到建出完整的图,或出现负度等明显不合理的情况。
将顶点进行排序,去掉度m最大的点,依次让其后m个数减1,若后面的某个顶点出现负数的情况或后面的数的个数少于最大的度则不能构成图

举例:序列S:7,7,4,3,3,3,2,1  删除序列S的首项 7 ,对其后的7项每项减1,得到:6,3,2,2,2,1,0,继续删除序列的首项6,对其后的6项每项减1,得到:2,1,1,1,0,-1,到这一步出现了负数,因此该序列是不可图的

排好序后为d1,d2,d3,d4....dn,设度数最大的为v1,将它与度数次大的前d1个顶点连边,然后这个顶点就可以不管了,及在序列中删除首项d1,并把后面的d1个度数减1,依次下去,知道所有的为0就是可图的,出现负数,就一定不可图..

对于这个应用,可以做做POJ 1659....


给定n个节点的度,问这n个节点是否可以组成结点度恰好为给出的一幅图。

Havel-Hakimi定理(判断一个序列是否可图)

1,Havel-Hakimi定理主要用来判定一个给定的序列是否是可图的。

2,首先介绍一下度序列:若把图G 所有顶点的度数排成一个序列S,则称S 为图G 的度序列。

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

4,判定过程:

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

(2)从S[2]开始对其后S[1]个数字-1

(3)一直循环直到当前序列出现负数(即不是可图的情况)或者当前序列全为0 (可图)时退出。

5,举例:序列S:7,7,4,3,3,3,2,1  删除序列S的首项7 ,

对其后的7项每项减1,得到:6,3,2,2,2,1,0,排序后继续删除序列的首项6,

对其后的6项每项减1,得到:2,1,1,1,0,-1,到这一步出现了负数,因此该序列是不可图的

6.我解释一下意思:排好序后为d1,d2,d3,d4....dn,

设度数最大的为v1,将它与度数次大的前d1个顶点连边,

然后这个顶点就可以不管了,及在序列中删除首项d1,

并把后面的d1个度数减1,依次下去,知道所有的为0就是可图的,出现负数,就一定不可图..

 


类似题目如下:

Problem C

Graph Construction

Time Limit

2 Seconds

Graph is a collection of edges E and vertices V. Graph has a wide variety of applications in computer. There are different ways to represent graph in computer. It can be represented by adjacency matrix or by adjacency list. There are some other ways to represent graph. One of them is to write the degrees (the numbers of edges that a vertex has) of each vertex. If there are n vertices then n integers can represent that graph. In this problem we are talking about simple graph which does not have same endpoints for more than one edge, and also does not have edges with the same endpoint.

Any graph can be represented by n number of integers. But the reverse is not always true. If you are given nintegers, you have to find out whether this n numbers can represent the degrees of n vertices of a graph.

Input
Each line will start with the number n (≤ 10000). The next n integers will represent the degrees of nvertices of the graph. A 0 input for n will indicate end of input which should not be processed.

Output
If the n integers can represent a graph then print “Possible”. Otherwise print “Not possible”. Output for each test case should be on separate line.

Sample Input

Output for Sample Input

4 3 3 3 3
6 2 4 5 5 2 1
5 3 2 3 2 1
0

Possible
Not possible
Not possible

算是这个定理的裸地应用!
wa了若干次。。。。。
主要是定理没看清楚!!!
若n = 后面第二小度数
那么是后面n个数-1
而不是全部-1!!!!!!
ac代码如下:
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <sstream>
#include <vector>
#include <stack>
#include <map>
#include <queue>
#include <iostream>
#include <stdlib.h>
#define rep(i,s,e) for(int i = (s);i<=(e);++i)
#define maxn 100000
#define INF 1000000000
using namespace std;
//10720
int num[maxn];
int n;
bool Havel_Hakimi()
{
    for(int i = 0;i<n;++i)
    {
        sort(num+i,num+n,greater<int>());
        //当前最大度必须小于当前点的个数
        //即num[i]<n-i  ==> num[i]+i<n
        if(i+num[i]>=n) return false;

        for(int j = i+1;j<=i+num[i];++j)//
        {
            num[j]--;
            if(num[j]<0)
             return false;
        }
    }
    if(num[n-1]!=0)//当剩下来的都是0时就可以构成图
    return false;
    return true;
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(scanf("%d",&n)==1)
    {
        if(n==0)
        break;

        bool flag = true;
        int sum = 0;
        for(int i = 0;i<n;++i)
        {
        scanf("%d",&num[i]);
        if(num[i]>=n)
        flag = false;
        sum += num[i];
        }
        //bool flag = Havel_Hakimi(n);
        if(sum%2!=0)
        flag = false;
        if(flag&&Havel_Hakimi())
        //if(flag)
        printf("Possible\n");
        else
        printf("Not possible\n");

    }
    return 0;
}
类似题目稍微复杂!

Frogs' Neighborhood
Time Limit: 5000MS Memory Limit: 10000K
Total Submissions: 5757 Accepted: 2473 Special Judge

Description

未名湖附近共有N个大小湖泊L1L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N)。如果湖泊LiLj之间有水路相连,则青蛙FiFj互称为邻居。现在已知每只青蛙的邻居数目x1x2, ..., xn,请你给出每两个湖泊之间的相连关系。

Input

第一行是测试数据的组数T(0 ≤ T ≤ 20)。每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1x2,..., xn(0 ≤ xi ≤ N)。

Output

对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用N×N的矩阵表示湖泊间的相邻关系,即如果湖泊i与湖泊j之间有水路相连,则第i行的第j个数字为1,否则为0。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。相邻两组测试数据之间输出一个空行。

Sample Input

3
7
4 3 1 5 4 2 1 
6
4 3 1 4 2 0 
6
2 3 1 1 2 1 

Sample Output

YES
0 1 0 1 1 0 1 
1 0 0 1 1 0 0 
0 0 0 1 0 0 0 
1 1 1 0 1 1 0 
1 1 0 1 0 1 0 
0 0 0 1 1 0 0 
1 0 0 0 0 0 0 

NO

YES
0 1 0 0 1 0 
1 0 0 1 1 0 
0 0 0 0 0 1 
0 1 0 0 0 0 
1 1 0 0 0 0 
0 0 1 0 0 0 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值