ZOJ3732 Graph Reconstruction Havel-Hakimi定理
分析:
给定一个非负整数序列{dn},若存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化。
进一步,若图为简单图,则称此序列可简单图化 (来自百度百科)
可简单图化的判定可以用Havel-Hakimi定理,然后简述 Havel-Hakimi定理
Havel-Hakimi定理的过程:
1,按度数排序。
2,选取度数最大的点,如果该点度数为0,结束,有解
3,每次选一个度数最大的点,然后将后面的点的度数依次减1,表示该顶点和相应的顶点有边相连,
如果有点的度数减到负数,结束,无解。
4,重复进行步骤1
然后这个题不只是判定有没有解,还需要判断是否有多解
“个人认为此题的难点在于多解时要输出两个。在Havel-Hakimi定理的构造过程中,如果把某两个点“互换”,那么就可以构造出多解的,
那么什么样的两个点才可以互换呢,比如我现在已经排完序,要减的度数序列一直到p,这时,如果p+1的点的度数和p是相同的,
那么p位置和p+1是可以"互换“的,连这两个点中的哪一个都不会影响结果。”(该段文字引用网上某大牛的想法)
所以通过判断p和p+1是否相等,就可以判断是否多解
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=1e2+;
const int INF=0x3f3f3f3f;
int a[N],d[N],c[N],n;
bool cmp(int x,int y)
{
return c[x]>c[y];
}
bool check()
{
for(int i=;i<=n;++i)c[i]=d[i];
for(int i=; i<=n; ++i)
{
sort(a+,a++n,cmp);
if(!c[a[]])break;
for(int j=,cnt=; j<=n&&cnt<=c[a[]]; ++j,++cnt)
{
--c[a[j]];
if(c[a[j]]<)return ;
}
c[a[]]=;
}
return ;
}
struct Edge
{
int u,v;
} x[N*N];
bool checkmul()
{
for(int i=; i<=n; ++i)c[i]=d[i];
for(int i=; i<=n; ++i)
{
sort(a+,a++n,cmp);
if(!c[a[]])break;
int k=c[a[]]+;
if(k<=n&&c[a[k]]==c[a[k-]])return ;
for(int j=,cnt=; j<=n&&cnt<=c[a[]]; ++j,++cnt)
--c[a[j]];
c[a[]]=;
}
return ;
}
void print()
{
int tot=;
for(int i=; i<=n; ++i)c[i]=d[i];
for(int i=; i<=n; ++i)
{
sort(a+,a++n,cmp);
if(!c[a[]])break;
for(int j=,cnt=; j<=n&&cnt<=c[a[]]; ++j,++cnt)
{
--c[a[j]];
++tot;
x[tot].u=a[],x[tot].v=a[j];
}
c[a[]]=;
}
for(int i=; i<=tot; ++i)
{
printf("%d",x[i].u);
if(i<tot)printf(" ");
}
printf("\n");
for(int i=; i<=tot; ++i)
{
printf("%d",x[i].v);
if(i<tot)printf(" ");
}
printf("\n");
}
int main()
{
while(~scanf("%d",&n))
{
int sum=;
for(int i=; i<=n; ++i)
{
scanf("%d",&d[i]);
sum+=d[i];
a[i]=i;
}
if(!check())
{
printf("IMPOSSIBLE\n");
continue;
}
if(checkmul())
{
printf("MULTIPLE\n");
printf("%d %d\n",n,sum/);
print();
printf("%d %d\n",n,sum/);
for(int i=; i<=n; ++i)c[i]=d[i];
int tot=;
bool flag=;
for(int i=; i<=n; ++i)
{
sort(a+,a++n,cmp);
if(!c[a[]])break;
if(flag)
{
int k=c[a[]]+;
if(k<=n&&c[a[k]]==c[a[k-]])
swap(a[k],a[k-]),flag=;
}
for(int j=,cnt=; j<=n&&cnt<=c[a[]]; ++j,++cnt)
{
--c[a[j]];
++tot;
x[tot].u=a[],x[tot].v=a[j];
}
c[a[]]=;
}
for(int i=; i<=tot; ++i)
{
printf("%d",x[i].u);
if(i<tot)printf(" ");
}
printf("\n");
for(int i=; i<=tot; ++i)
{
printf("%d",x[i].v);
if(i<tot)printf(" ");
}
printf("\n");
}
else
{
printf("UNIQUE\n");
printf("%d %d\n",n,sum/);
print();
}
}
return ;
}
ZOJ3732 Graph Reconstruction Havel-Hakimi定理的更多相关文章
- POJ1659 Frogs' Neighborhood(Havel–Hakimi定理)
题意 题目链接 \(T\)组数据,给出\(n\)个点的度数,问是否可以构造出一个简单图 Sol Havel–Hakimi定理: 给定一串有限多个非负整数组成的序列,是否存在一个简单图使得其度数列恰为这 ...
- 2013长沙 G Graph Reconstruction (Havel-Hakimi定理)
Graph Reconstruction Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge Let there ...
- zoj3732&& hdu4797 Graph Reconstruction
Graph Reconstruction Time Limit: 2 Seconds Memory Limit: 65536 KB Special Judge Let there ...
- 2013亚洲区域赛长沙站 ZOJ 3732 Graph Reconstruction
题目链接 Graph Reconstruction 题意 给你无向图每个点的度数, 问是否存在唯一解, 存在输出唯一解, 多解输出两个, 无解输出IMPOSSIBLE 思路 这里用到了 Havel-H ...
- Codeforces Round #192 (Div. 1) C. Graph Reconstruction 随机化
C. Graph Reconstruction Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/3 ...
- CodeForces-329C(div1):Graph Reconstruction(随机&构造)
I have an undirected graph consisting of n nodes, numbered 1 through n. Each node has at most two in ...
- Spectral Graph Theory的一些定理
邻接矩阵的特征值和特征向量不会随着节点的排列不同而变化.两个图同构可以推出他们的邻接矩阵具有相同的特征值和特征向量,但是反过来不行.
- POJ 1659 Frogs' Neighborhood(可图性判定—Havel-Hakimi定理)【超详解】
Frogs' Neighborhood Time Limit: 5000MS Memory Limit: 10000K Total Submissions: 9897 Accepted: 41 ...
- Codeforces 1091E New Year and the Acquaintance Estimation Erdős–Gallai定理
题目链接:E - New Year and the Acquaintance Estimation 题解参考: Havel–Hakimi algorithm 和 Erdős–Gallai theore ...
随机推荐
- Java知识总结--JDBC&XML
1说说jdbc连接数据库的步骤 1.注册驱动 2.获得连接 3.执行sql语句 4.获得结果集,进行结果集的处理 5.关闭结果集 6.关闭连接,释放资源 2 statement 和preparedst ...
- 我忽略了的DOCTYPE!
最近不知道是不是因为天气的原因,瞌睡太多了,而且每天晚上都做梦,更奇怪的是每次做梦都能够连着上次没有做完的梦继续做.第二天上班又没有精神,人都快崩溃了!不说了,郁闷! 偶然看到一个问题:Doctype ...
- 判断浏览器是否支持某个css3属性的javascript方法
判断浏览器是否支持css3某个属性的方法: /** * 判断浏览器是否支持某一个CSS3属性 * @param {String} 属性名称 * @return {Boolean} true/false ...
- -----IT男生涯————初始篇
大家好,我是kuuga,一名普通大学的在读生.其实,当时我不知道为什么会选择计算机这个学院,而且还选择了网络工程这个坑爹的专业.为什么说坑爹呢?因为几年学生生涯中编程已经占了很多时间和课程,至于我的专 ...
- spring-boot 整合redis作为数据缓存
添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...
- CODEVS 3657 括号序列
[问题描述] 我们用以下规则定义一个合法的括号序列: (1)空序列是合法的 (2)假如S是一个合法的序列,则 (S) 和[S]都是合法的 (3)假如A 和 B 都是合法的,那么AB和BA也是合法的 例 ...
- js为链接绑定点击事件并且附带return false;来阻止跳转
<!DOCTYPE HTML> <html> <head> <meta charset="gb2312" /> <title& ...
- [转载]MongoDB学习 (六):查询
本文地址:http://www.cnblogs.com/egger/archive/2013/06/14/3135847.html 欢迎转载 ,请保留此链接๑•́ ₃•̀๑! 本文将介绍操作符的使用 ...
- uva 1475 - Jungle Outpost
半平面交,二分: 注意,题目的点是顺时针给出的: #include<cstdio> #include<algorithm> #include<cmath> #def ...
- poj 1811 Prim test
基本上一个裸的Miller_Rabin大素数判定和一个裸的Pollard_rho素数分解算法,当模板用吧! #include<cstdio> #include<algorithm&g ...