poj 1659 Frogs' Neighborhood Havel-Hakimi定理 可简单图定理

作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4098136.html

给定一个非负整数序列$D=\{d_1,d_2,...d_n\}$,若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化。进一步,若图为简单图,则称此序列可简单图化。

可图化的判定为:$d_1+d_2+ \cdots +d_n=0(mod2)$。即把奇数度的点配对,剩下的变为自环。
可简单图化的判定,即Havel-Hakimi定理:

我们把序列$D$变换为非增序列,即$d_1\geq d_2\geq \cdots \geq d_n$,则$D$可简单图化当且仅当$D‘=(d_2-1, d_3-1, \cdots ,d_{(d1+1)}-1, d_{d1+2}, d_{d1+3}, \cdots ,d_n)$可简单图化。

证明:

<--:若$D‘$可简单图化,把原图$G_D$中的最大度点与$G_{D‘}$中度最大的$d_1$个点连边即可,图$G_D$必为简单图。

-->:若$D$可简单图化,设得到的简单图为$D_G$。分两种情况考虑:
(a)若$G_D$中存在边$(v_1,v_2), (v_1,v_3), \dots ,(v_1,v_{d_1+1})$,则删除这些边得简单图$G_{D‘}$,于是$D‘$可简单图化为$G_{D‘}$

(b)若存在点$v_i,v_j(i<j)$且$(v_1,v_i)$不在$G_D$中,但$(v_1,v_j)$在$G_D$中。这时,因为$d_i \geq d_j$,必存在$k$使得$(v_i, v_k)$在$D_G$中但$(v_j,v_k)$不在$G_D$中。这时我们可以令$G‘‘=G_D-\{(v_i,v_k),(v_1,v_j)\}+\{(v_k,v_j),(v_1,v_i)\}$。$G‘‘$的度序列仍为$D$,使用情况(a)处理。

例如对于下图,我们删除两条打红X的边,添加两条虚线的边,即可转化为$G‘‘$

代码实现很简单,每次对数组arr排序,然后对于arr[1],arr[2],...,arr[arr[0]]每个数减一,并另arr[0]=0。重复n次,最后检验数组是否全部为0,是则输出YES和图,否则输出NO。

需要注意的是输出格式,每两个case之间需要输出一个空行。

代码如下:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #define     MAXN 11
 7 using namespace std;
 8 class node
 9 {
10     public:
11         int id;
12         int degree;
13         bool operator < (const node & a)const
14         {
15             return degree>a.degree;
16         }
17 };
18 int n;
19 node arr[MAXN];
20 int map[MAXN][MAXN];
21 void solve()
22 {
23     memset(map, 0, sizeof(map));
24     for( int i = 0 ; i < n ; i++ )
25     {
26         sort(arr, arr+n);
27         for( int j = 1 ; j <= arr[0].degree ; j++ )
28         {
29             arr[j].degree -= 1;
30             map[arr[0].id][arr[j].id] = 1;
31             map[arr[j].id][arr[0].id] = 1;
32         }
33         arr[0].degree = 0;
34     }
35     for( int i = 0 ; i < n ; i++ )
36     {
37         if( arr[i].degree < 0 )
38         {
39             printf("NO\n\n");
40             return ;
41         }
42     }
43     printf("YES\n");
44     for( int i = 0 ; i < n ; i++ )
45     {
46         for( int j = 0 ; j < n ; j++ )
47         {
48             printf("%d%c", map[i][j], j==(n-1)?‘\n‘:‘ ‘);
49         }
50     }
51     printf("\n");
52 }
53 int main(int argc, char *argv[])
54 {
55     int t;
56     scanf("%d", &t);
57     while( t-- )
58     {
59         scanf("%d", &n);
60         for( int i = 0 ; i < n ; i++ )
61         {
62             scanf("%d", &arr[i].degree);
63             arr[i].id = i;
64         }
65         solve();
66     }
67 }

poj 1659 Frogs' Neighborhood Havel-Hakimi定理 可简单图定理

时间: 2024-08-04 14:13:38

poj 1659 Frogs' Neighborhood Havel-Hakimi定理 可简单图定理的相关文章

POJ 1659 Frogs&#39; Neighborhood(可图性判定—Havel-Hakimi定理)【超详解】

Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 9897   Accepted: 4137   Special Judge Description 未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N).如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居.现在已知每只青蛙的邻居数目x1, x2, ..

POJ 1659 Frogs&#39; Neighborhood 可图性判断-Havel定理

Description 未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N).如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居.现在已知每只青蛙的邻居数目x1, x2, ..., xn,请你给出每两个湖泊之间的相连关系. Input 第一行是测试数据的组数T(0 ≤ T ≤ 20).每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xi ≤ N

poj 1659 Frogs&#39; Neighborhood (Havel-Hakimi定理,判断序列是否可图)

链接:poj 1659 中文题不必解释题意... 其实质是给定一个度序列,判断是否可图, 若可图,输出YES,并输出各顶点之间的连边的情况 否则,输出NO 思路:判断一个序列是否可图,直接利用Havel-Hakimi定理即可 判断任意一个序列是否可图的具体过程: (1)先将序列由大到小排序 (2)设最大的度数为 t ,将最大项删除,然后把最大度数后 (不包括自己)的 t 个度数分别减1(意思就是把度数最大的点与后几个点连边) (3)重复上述两步,如果最大度数t超过了剩下顶点的个数, 或者序列中出

POJ 1659 Frogs&#39; Neighborhood Havel-Hakimi定理判断可图

1,Havel-Hakimi定理主要用来判定一个给定的序列是否是可图的. 2,首先介绍一下度序列:若把图 G 所有顶点的度数排成一个序列 S,则称 S 为图 G 的度序列. 3,一个非负整数组成的有限序列如果是某个无向图的序列,则称该序列是可图的. 4,判定过程:(1)按降序排序,进入步骤(2).(2)将第[2,2+s[1]-1]全部减1,若出现负数则不可图,判定结束.若[2,2+s[1]-1]全部变为0,则可图,判定结束.将s[1]删除,跳至步骤(1). #include <algorithm

POJ 1659 Frogs&#39; Neighborhood(度序列构图)

题意  中文 根据Havel-Hakimi定理构图就行咯  先把顶点按度数从大到小排序  可图的话  度数大的顶点与它后面的度数个顶点相连肯定是满足的  出现了-1就说明不可图了 #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N = 20; int mat[N][N], ord[N]; bool cmp(int i, int j) { retur

poj 1659 Frogs&#39; Neighborhood

#include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map> #include <string> #include <ma

poj 1659 Frogs&#39; Neighborhood (构图)

Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 7237   Accepted: 3123   Special Judge Description 未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ i ≤ N).如果湖泊Li和Lj之间有水路相连,则青蛙Fi和Fj互称为邻居.现在已知每只青蛙的邻居数目x1, x2, ..

POJ 1659 Frogs&#39; Neighborhood (贪心)

题意:中文题. 析:贪心策略,先让邻居多的选,选的时候也尽量选邻居多的. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #include <iostream> #include <cstring>

Poj 1659 Frogs&#39; Neighborhood 图的可图性判断

/* 先将所有度数按从大到小排序,取最大的度数为N的节点,将其后面N个节点的度数减一,如果出现负数节点或者后面的节点数量不足N则可以判定无法构成图,重复这个过程,直到所有的度数都为零*/#include <cstdio> #include <iostream> #include <cstdlib> #include <algorithm> #include <set> #include <map> #include <vecto