ZOJ 3732 Graph Reconstruction Havel_Hakimi定理

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5078

题意:有N个点组成无向图,每个点的度为ai,问是否能组成图,并且组成的图方式是否唯一。

思路:Havel_Hakimi定理的应用。

(以下转载)

1,Havel-Hakimi定理主要用来判定一个给定的序列是否是可图的。

2,首先介绍一下度序列:若把图 G 所有顶点的度数排成一个序列 S,则称 S 为图 G 的度序列。

3,一个非负整数组成的有限序列如果是某个无向图的序列,则称该序列是可图的。

4,判定过程:(1)对当前数列排序,使其呈递减,(2)从S【2】开始对其后S【1】个数字-1,(3)一直循环直到当前序列出现负数(即不是可图的情况)或者当前序列全为0 (可图)时退出。

5,举例:序列S:7,7,4,3,3,3,2,1  删除序列S的首项 7 ,对其后的7项每项减1,得到:6,3,2,2,2,1,0,继续删除序列的首项6,对其后的6项每项减1,得到:2,1,1,1,0,-1,到这一步出现了负数,因此该序列是不可图的。

(转载结束)

判断是否成图方式唯一的方法是在每个点寻找连接的边的时候,找到的最后一个点,如果与它之后第一个度不为零的点的度是相同的,则两个点可以交换位置并且不影响建图可能性,而出现至少两种建图方式。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#define PI acos(-1.0)
#define maxn 10005
#define INF 0x7fffffff
#define eps 1e-8
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
struct aa
{
    int num;
    int degree;
} a[105],b[105];
int way[10005][2];
bool cmp1(aa a,aa b)
{
    return a.degree>b.degree;
}
int main()
{
    int tot;
    while(~scanf("%d",&tot))
    {
        int top=0,A,B;
        bool flag1=0,flag2=0;
        for(int i=0; i<tot; i++)
        {
            a[i].num=b[i].num=i;
            scanf("%d",&a[i].degree);
            b[i].degree=a[i].degree;
        }
        for(int i=0; i<tot; i++)
        {
            sort(b+i,b+tot,cmp1);
            if(i+b[i].degree>=tot)
            {
                flag1=1;
                break;
            }
            int tt=0;
            for(int j=i+1; j<tot; j++)
            {
                if(!b[j].degree)
                    continue;
                tt++;
                way[top][0]=b[i].num;
                way[top++][1]=b[j].num;
                if(tt==b[i].degree)
                {
                    int p=j+1;
                    while(b[p].degree==0&&p<tot)
                        p++;
                    if(p<tot&&b[p].degree==b[j].degree)
                        flag2=1;
                }
                b[j].degree--;
                if(b[j].degree<0)
                {
                    flag1=1;
                    break;
                }
                if(tt==b[i].degree)
                    break;
            }
            if(tt<b[i].degree)
                flag1=1;
            if(flag1==1)
                break;
        }
        if(!flag1&&!flag2)
        {
            printf("UNIQUE\n");
            printf("%d %d\n",tot,top);
            for(int i=0; i<top; i++)
            {
                if(i==0)
                    printf("%d",way[i][0]+1);
                else printf(" %d",way[i][0]+1);
            }
            printf("\n");
            for(int i=0; i<top; i++)
            {
                if(i==0)
                    printf("%d",way[i][1]+1);
                else printf(" %d",way[i][1]+1);
            }
            printf("\n");
        }
        else if(flag1)
            printf("IMPOSSIBLE\n");
        else
        {
            printf("MULTIPLE\n");
            printf("%d %d\n",tot,top);
            for(int i=0; i<top; i++)
            {
                if(i==0)
                    printf("%d",way[i][0]+1);
                else printf(" %d",way[i][0]+1);
            }
            printf("\n");
            for(int i=0; i<top; i++)
            {
                if(i==0)
                    printf("%d",way[i][1]+1);
                else printf(" %d",way[i][1]+1);
            }
            printf("\n");
            printf("%d %d\n",tot,top);
            top=0;
            flag2=0;
            for(int i=0; i<tot; i++)
                b[i]=a[i];
            for(int i=0; i<tot; i++)
            {
                sort(b+i,b+tot,cmp1);
                if(i+b[i].degree>=tot)
                {
                    flag1=1;
                    break;
                }
                int tt=0;
                for(int j=i+1; j<tot; j++)
                {
                    if(!b[j].degree)
                        continue;
                    tt++;
                    if(tt==b[i].degree&&flag2==0)
                    {
                        int p=j+1;
                        while(b[p].degree==0&&p<tot)
                            p++;
                        if(p<tot&&b[p].degree==b[j].degree)
                        {
                            flag2=1;
                            j=p;
                        }
                    }
                    way[top][0]=b[i].num;
                    way[top++][1]=b[j].num;
                    b[j].degree--;
                    if(tt==b[i].degree)
                        break;
                }
            }
            for(int i=0; i<top; i++)
            {
                if(i==0)
                    printf("%d",way[i][0]+1);
                else printf(" %d",way[i][0]+1);
            }
            printf("\n");
            for(int i=0; i<top; i++)
            {
                if(i==0)
                    printf("%d",way[i][1]+1);
                else printf(" %d",way[i][1]+1);
            }
            printf("\n");
        }
    }
    return 0;
}

ZOJ 3732 Graph Reconstruction Havel_Hakimi定理

时间: 2024-10-12 07:46:16

ZOJ 3732 Graph Reconstruction Havel_Hakimi定理的相关文章

UVA 12382 Grid of Lamps ZOJ 3732 Graph Reconstruction 可图判定性

Uva 12382 题目链接:点击打开链接 ZOJ 3732题解:点击打开链接 Uva12382 题意: 给定n*m的地板,每个地板上有一盏灯,要么亮要么暗. 下面n个数字表示每行至少亮的灯盏数 下面m个数字表示每列至少亮的灯盏数 求:开始灯都是暗的,最少点亮几盏灯能满足上述条件 思路: 先给行和列大到小排序,然后每次用行减掉列.减完后再排个序即可. 即:实时排序. #include <cstdio> #include <cstring> #include <iostream

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

Graph Reconstruction Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Let there be a simple graph with N vertices but we just know the degree of each vertex. Is it possible to reconstruct the graph only by these information? A sim

zoj3732&amp;&amp; hdu4797 Graph Reconstruction

Graph Reconstruction Time Limit: 2 Seconds      Memory Limit: 65536 KB      Special Judge Let there be a simple graph with N vertices but we just know the degree of each vertex. Is it possible to reconstruct the graph only by these information? A sim

uva10720 - Graph Construction(Havel-Hakimi定理)

题目:uva10720 - Graph Construction(Havel-Hakimi定理) 题目大意:给出N个点,并且给出每个点的度,问能否形成简单图. 解题思路:一开始自己写想了些形成简单图的条件,例如度数之和是偶数,度数的一半也就是简单图的边不能超过n * (n - 1) / 2,每个顶点的度数都应该小于总的顶点个数,但后面发现这些只是必要的条件.后来看了题解发现大神们都是用Havel-Hakimi定理. 定理大致内容就是每次都将度数最大的点拿出来,然后分别和每个顶点形成一条边,这样这

CUGBACM_Summer_Tranning3

A.ZOJ3726 Alice's Print Service 题解 here 这道题在HDU上要用I64d 在ZOJ上要用lld C.ZOJ3728 Collision 几何题,分几种情况:和大圆相离.和大圆相交和小圆相离.和大圆相交小圆也相交. 还有一种情况需要考虑,它飞的方向远离圆则永远不相交. 借用土豪的神模板 #include<cstring> #include<string> #include<fstream> #include<iostream>

2018省赛赛第一次训练题解和ac代码

第一次就去拉了点思维很神奇的CF题目 # Origin Title     A CodeForces 607A Chain Reaction     B CodeForces 385C Bear and Prime Numbers     C CodeForces 670D2 Magic Powder - 2     D CodeForces 360B Levko and Array     E CodeForces 68B Energy exchange     F CodeForces 24

ZOJ 3696 Alien&#39;s Organ(泊松定理,期望值)

Alien's Organ Time Limit: 2 Seconds      Memory Limit: 65536 KB There's an alien whose name is Marjar. It is an universal solder came from planet Highrich a long time ago. Marjar is a strange alien. It needs to generate new organs(body parts) to figh

HDU 2454 Degree Sequence of Graph G(Havel定理 判断简单图的存在)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2454 Problem Description Wang Haiyang is a strong and optimistic Chinese youngster. Although born and brought up in the northern inland city Harbin, he has deep love and yearns for the boundless oceans.

HDU 2454 Degree Sequence of Graph G (可简单图化的判定 havel定理)

题目链接:HDU 2454 Degree Sequence of Graph G 题意:给出N个点的度(简单图),问能能否画出个图,(其实就是给出一个串非负的序列是否有对应的图存在) 没见过这个定理 题意真的难懂. havel定理就是一个给出一串非负的序列,存在一个无向图使得图中各点的度与此序列一一对应,则称此序列可图化.简单图的话就是,可简单图化. 可简单图化的判定(Havel定理):把序列排成不增序,即d1>=d2>=-->=dn,则d可简单图化当且仅当d'={d2-1,d3-1,-