分析:

给定一个非负整数序列{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. linear-gradient 的“高能”用法

    首先,让我们来了解一下“linear-gradient”的基本用法: 说明:用线性渐变创建图像 语法: <linear-gradient> = linear-gradient([ [ &l ...

  2. 用PHP实现单向链表

    供参考,代码还可继续打磨 同时放在了我的github上:https://github.com/hheedat/demo/blob/master/learn_php/58_linked_list.php ...

  3. Linux下GPIO驱动(一) ----一个简单的LED驱动

    /******************************* * *杂项设备驱动:miscdevice *majior=10; * * *****************************/ ...

  4. emctl start dbconsole OC4J_dbconsole*** not found

    C:\windows\system32>emctl start dbconsole OC4J Configuration issue. D:\app\product\\db_1/oc4j/j2e ...

  5. shell中的重定向(2>&1)

    shell的输出可以分为标准输出和错误输出,2>&1中,2代表错误输出,1代表标准输出,&符号代表后面跟的是代号而不是文件. test.sh echo '我是标准输出' ls / ...

  6. 让WPF的Popup不总置顶的解决方案

    使用WPF的Popup的时候会发现有一个问题,它总是会置顶,只要Popup的StayOpen不设置为False,它就一直呆在最顶端,挡住其他的窗口. 解决方案是继承Popup重新定义控件PopupEx ...

  7. Ubuntu 下部署asp.net运行环境

    在Ubuntu下部署asp.net运行环境,网上教程很多,基本都是编译Mono源码,然后安装jexus.但是可能是我最近RP不太好,编译Mono源码一直都是失败,无奈之下只好找另外的方法安装了. 网上 ...

  8. hdu 1427 dfs

    速算24点 题意:随机给你四张牌,包括 A(1),2,3,4,5,6,7,8,9,10,J(11),Q(12),K(13).要求只用'+','-','*','/'运算符以及括号改变运算 顺序,使得最终 ...

  9. 【Scala 】Akka库

    简介编辑 Akka 是一个用 Scala 编写的库,用于简化编写容错的.高可伸缩性的 Java 和 Scala 的 Actor 模型应用.它已经成功运用在电信行业.系统几乎不会宕机(高可用性 99.9 ...

  10. 【配置文件节点】java世界配置文件节点

    Spring <context:property-placeholder/> 期望:能不能有一种解决方案可以方便我们在一个阶段内不需要频繁书写一个参数的值,而在不同阶段间又可以方便的切换参 ...