分析:

给定一个非负整数序列{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定理的更多相关文章

  1. POJ1659 Frogs' Neighborhood(Havel–Hakimi定理)

    题意 题目链接 \(T\)组数据,给出\(n\)个点的度数,问是否可以构造出一个简单图 Sol Havel–Hakimi定理: 给定一串有限多个非负整数组成的序列,是否存在一个简单图使得其度数列恰为这 ...

  2. 2013长沙 G Graph Reconstruction (Havel-Hakimi定理)

    Graph Reconstruction Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Let there ...

  3. zoj3732&& hdu4797 Graph Reconstruction

    Graph Reconstruction Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Let there ...

  4. 2013亚洲区域赛长沙站 ZOJ 3732 Graph Reconstruction

    题目链接 Graph Reconstruction 题意 给你无向图每个点的度数, 问是否存在唯一解, 存在输出唯一解, 多解输出两个, 无解输出IMPOSSIBLE 思路 这里用到了 Havel-H ...

  5. Codeforces Round #192 (Div. 1) C. Graph Reconstruction 随机化

    C. Graph Reconstruction Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/3 ...

  6. 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 ...

  7. Spectral Graph Theory的一些定理

    邻接矩阵的特征值和特征向量不会随着节点的排列不同而变化.两个图同构可以推出他们的邻接矩阵具有相同的特征值和特征向量,但是反过来不行.

  8. POJ 1659 Frogs' Neighborhood(可图性判定—Havel-Hakimi定理)【超详解】

    Frogs' Neighborhood Time Limit: 5000MS   Memory Limit: 10000K Total Submissions: 9897   Accepted: 41 ...

  9. 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 ...

随机推荐

  1. Java知识总结--JDBC&XML

    1说说jdbc连接数据库的步骤 1.注册驱动 2.获得连接 3.执行sql语句 4.获得结果集,进行结果集的处理 5.关闭结果集 6.关闭连接,释放资源 2 statement 和preparedst ...

  2. 我忽略了的DOCTYPE!

    最近不知道是不是因为天气的原因,瞌睡太多了,而且每天晚上都做梦,更奇怪的是每次做梦都能够连着上次没有做完的梦继续做.第二天上班又没有精神,人都快崩溃了!不说了,郁闷! 偶然看到一个问题:Doctype ...

  3. 判断浏览器是否支持某个css3属性的javascript方法

    判断浏览器是否支持css3某个属性的方法: /** * 判断浏览器是否支持某一个CSS3属性 * @param {String} 属性名称 * @return {Boolean} true/false ...

  4. -----IT男生涯————初始篇

    大家好,我是kuuga,一名普通大学的在读生.其实,当时我不知道为什么会选择计算机这个学院,而且还选择了网络工程这个坑爹的专业.为什么说坑爹呢?因为几年学生生涯中编程已经占了很多时间和课程,至于我的专 ...

  5. spring-boot 整合redis作为数据缓存

    添加依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>sp ...

  6. CODEVS 3657 括号序列

    [问题描述] 我们用以下规则定义一个合法的括号序列: (1)空序列是合法的 (2)假如S是一个合法的序列,则 (S) 和[S]都是合法的 (3)假如A 和 B 都是合法的,那么AB和BA也是合法的 例 ...

  7. js为链接绑定点击事件并且附带return false;来阻止跳转

    <!DOCTYPE HTML> <html> <head> <meta charset="gb2312" /> <title& ...

  8. [转载]MongoDB学习 (六):查询

    本文地址:http://www.cnblogs.com/egger/archive/2013/06/14/3135847.html  欢迎转载 ,请保留此链接๑•́ ₃•̀๑! 本文将介绍操作符的使用 ...

  9. uva 1475 - Jungle Outpost

    半平面交,二分: 注意,题目的点是顺时针给出的: #include<cstdio> #include<algorithm> #include<cmath> #def ...

  10. poj 1811 Prim test

    基本上一个裸的Miller_Rabin大素数判定和一个裸的Pollard_rho素数分解算法,当模板用吧! #include<cstdio> #include<algorithm&g ...