POJ 1659 Frogs' Neighborhood(Havel方法)
2014-05-18 23:56
501 查看
说的复杂了是Havel方法, 实际上能通过分析找出规律
目给出n个池塘, 告诉每个池塘相邻池塘的个数, 问是否存在一种池塘的分布符合题目的要求
显然应该先处理最多的, 因为它与大部分池塘发生联系, 假设池塘i相邻的池塘有xi个, 则处理完池塘i之后, 有另外xi个池塘的相邻池塘数xj会减小1.
为了保证相邻池塘数多的池塘都能符合要求, 应该从池塘数多的池塘进行减1操作
另外给出Havel方法的证明
给定一个非负整数序列{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个点之间连边,然后这个点就可以不管了,一直继续这
个过程,直到建出完整的图,或出现负度等明显不合理的情况。
对于一个给定的度序列,看能不能形成一个简单无向图。
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,能构成图,跳出!
2 1 1 1
第二步后0 0 0 1
排完续后1 0 0 0
第二步后0 -1 0 0
出现负数,直接退出!
目给出n个池塘, 告诉每个池塘相邻池塘的个数, 问是否存在一种池塘的分布符合题目的要求
显然应该先处理最多的, 因为它与大部分池塘发生联系, 假设池塘i相邻的池塘有xi个, 则处理完池塘i之后, 有另外xi个池塘的相邻池塘数xj会减小1.
为了保证相邻池塘数多的池塘都能符合要求, 应该从池塘数多的池塘进行减1操作
另外给出Havel方法的证明
给定一个非负整数序列{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个点之间连边,然后这个点就可以不管了,一直继续这
个过程,直到建出完整的图,或出现负度等明显不合理的情况。
对于一个给定的度序列,看能不能形成一个简单无向图。
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,能构成图,跳出!
2 1 1 1
第二步后0 0 0 1
排完续后1 0 0 0
第二步后0 -1 0 0
出现负数,直接退出!
#include <iostream> #include <cstring> #include <fstream> #include <algorithm> using namespace std; struct Node { int xu, num; } q[12]; int g[12][12]; int cmp(Node a, Node b) { return a.num > b.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) { sort(q+1, q+n+1, cmp); if(q[1].num == 0) break; for(i = 1; i <= q[1].num; i++) { q[1+i].num--; 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; break; } } if(flag == 1) break; q[1].num = 0; } 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; }
相关文章推荐
- poj 1659 Frogs' Neighborhood (Havel-Hakimi定理,判断序列是否可图)
- Havel-Hakimi 度序列判断无向图是否可图 Poj 1659 Frogs' Neighborhood
- POJ 1659 - Frogs' Neighborhood , Havel_Hakimi 定理
- POJ 1659.Frogs' Neighborhood(Havel-Hakimi算法应用)
- poj1659 Frogs' Neighborhood 根据度数列构造图,havel_hakimi算法
- POJ 1659 Frogs' Neighborhood(Havel_Hakimi定理,图论基础)
- POJ-1659-Frogs' Neighborhood (Havel-Hakimi定理)
- POJ:1659 Frogs' Neighborhood (Havel-Hakimi定理)
- POJ 1659:Frogs' Neighborhood(Havel-Hakimi定理)
- POJ 1659 Frogs' Neighborhood
- poj 1659 Frogs' Neighborhood (判定度序列的可图性) .
- POJ-1659-Frogs' Neighborhood
- poj Frogs' Neighborhood(1659)
- POJ 1659 Frogs' Neighborhood(度序列构图)
- POJ_1659_Frogs' Neighborhood
- poj 1659 Frogs' Neighborhood
- 【Havel-Hakimi定理】PKU-1659-Frogs' Neighborhood
- Havel-Hakimi定理(度序列可图性的判定)&POJ 1659 Frogs' Neighborhood
- POJ 1659 Frogs' Neighborhood
- poj 1659 Frogs' Neighborhood (度序列)