zoukankan      html  css  js  c++  java
  • POJ 1659【Havel-Hakimi 定理】

    Havel-Hakimi 定理:

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

    例如,判断序列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,

    到这一步出现了负数。由于图中不可能存在负度数的顶点,因此该序列不是可图的。

    再举一个例子,判断序列s: 5, 4, 3, 3, 2, 2, 2, 1, 1, 1 是否是可图的。

    删除序列s 的首项5,对其后的5 项每项减1,得到:3, 2, 2, 1, 1, 2, 1, 1, 1,

    重新排序后为:3, 2, 2, 2, 1, 1, 1, 1, 1。

    继续删除序列的首项3,对其后的3 项每项减1,得到:1, 1, 1, 1, 1, 1, 1, 1。

    如此再陆续得到序列:1, 1, 1, 1, 1,1, 0;1, 1, 1, 1, 0, 0;1, 1, 0, 0, 0;0, 0, 0, 0。

    由此可判定该序列是可图的。

    Havel-Hakimi 定理实际上给出了根据一个序列s 构造图(或判定s 不是可图的)的方法:把序列s 按照非增顺序

    排序以后,其顺序为d1, d2, …, dn;度数最大的顶点(设为v1),将它与度数次大的前d1 个顶点之间连边,然

    后这个顶点就可以不管了,即在序列中删除首项d1,并把后面的d1个度数减1;再把剩下的序列重新按非增顺序排

    序,按照上述过程连边;…;直到建出完整的图,或出现负度数等明显不合理的情况为止。


    再回到本题:

    Frogs' Neighborhood
    Time Limit: 5000MS Memory Limit: 10000K
    Total Submissions: 10443 Accepted: 4340 Special Judge

    Description

    未名湖附近共有N个大小湖泊L1, L2, ..., Ln(其中包括未名湖),每个湖泊Li里住着一只青蛙Fi(1 ≤ iN)。如果湖泊LiLj之间有水路相连,则青蛙FiFj互称为邻居。现在已知每只青蛙的邻居数目x1, x2, ..., xn,请你给出每两个湖泊之间的相连关系。

    Input

    第一行是测试数据的组数T(0 ≤ T ≤ 20)。每组数据包括两行,第一行是整数N(2 < N < 10),第二行是N个整数,x1, x2,..., xn(0 ≤ xiN)。

    Output

    对输入的每组测试数据,如果不存在可能的相连关系,输出"NO"。否则输出"YES",并用N×N的矩阵表示湖泊间的相邻关系,即如果湖泊i与湖泊j之间有水路相连,则第i行的第j个数字为1,否则为0。每两个数字之间输出一个空格。如果存在多种可能,只需给出一种符合条件的情形。相邻两组测试数据之间输出一个空行。

    Sample Input

    3
    7
    4 3 1 5 4 2 1 
    6
    4 3 1 4 2 0 
    6
    2 3 1 1 2 1 
    

    Sample Output

    YES
    0 1 0 1 1 0 1 
    1 0 0 1 1 0 0 
    0 0 0 1 0 0 0 
    1 1 1 0 1 1 0 
    1 1 0 1 0 1 0 
    0 0 0 1 1 0 0 
    1 0 0 0 0 0 0 
    
    NO
    
    YES
    0 1 0 0 1 0 
    1 0 0 1 1 0 
    0 0 0 0 0 1 
    0 1 0 0 0 0 
    1 1 0 0 0 0 
    0 0 1 0 0 0 
    

    注意:由该定理得到的图是不唯一的。

    题解:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <vector>
    #include <set>
    #include <map>
    #define INF
    using namespace std;
    const int maxn=105;
    int t,n;
    int e[maxn][maxn];
    struct node{
        int degree;//顶点的度数
        int num;//顶点的编号
    }a[maxn];
    bool cmp(node a,node b){//度数由大到小排序
        return a.degree>b.degree;
    }
    int main()
    {
        scanf("%d",&t);
        while(t--){
            memset(e,0,sizeof e);
            scanf("%d",&n);
            for(int i=0;i<n;i++){
                scanf("%d",&a[i].degree);
                a[i].num=i+1;//顶点编号由1-n
            }
            int flag=1;//旗帜变量
            for(int i=0;i<n;i++){
                sort(a,a+n,cmp);
                if(a[i].degree>n-i-1){//如果后序顶点的数量小于当前顶点的度数,则无法构成图
                    flag=0;
                    break;
                }
                for(int j=i+1;j<=a[i].degree+i&&j<n;j++){
                    a[j].degree--;
                    if(a[j].degree<0){
                        flag=0;
                        break;
                    }
                    e[a[i].num][a[j].num]=e[a[j].num][a[i].num]=1;//连边
                }
            }
            if(flag){
                printf("YES
    ");
                for(int i=1;i<=n;i++){
                    for(int j=1;j<=n;j++){
                        printf("%d",e[i][j]);
                        if(j!=n)
                            printf(" ");
                    }
                    printf("
    ");
                }
            }else
                printf("NO
    ");
            printf("
    ");
        }
        return 0;
    }
    




  • 相关阅读:
    Redis 学习目录
    Knockout 官网学习文档目录
    C# 知识点回忆..
    爬虫-HtmlAgilityPack
    net core 3.1 知识累积
    共享文件夹(局域网)报错:The username or password is incorrect
    使用 Beyond Compare 工具比较合并 TFS 管理的代码
    创建索引,SQL优化
    LINQ SelectMany代替for循环赋值,把联合查询的值赋值给第1个集合
    判断文件编码
  • 原文地址:https://www.cnblogs.com/kzbin/p/9205226.html
Copyright © 2011-2022 走看看