zoukankan      html  css  js  c++  java
  • BZOJ 1005: [HNOI2008]明明的烦恼(prufer数列)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1005

    题意:

    Description

      自从明明学了树的结构,就对奇怪的树产生了兴趣......给出标号为1到N的点,以及某些点最终的度数,允许在
    任意两点间连线,可产生多少棵度数满足要求的树?

    Input

      第一行为N(0 < N < = 1000),
    接下来N行,第i+1行给出第i个节点的度数Di,如果对度数不要求,则输入-1

    Output

      一个整数,表示不同的满足要求的树的个数,无解输出0

    思路:
    又了解了一个神奇的东西,prufer数列!!!

    prufer数列,可以用来解一些关于无根树计数的问题。

    prufer数列是一种无根树的编码表示,对于一棵n个节点带编号的无根树,对应唯一一串长度为n-1的prufer编码。

    (1)无根树转化为prufer序列。

    首先定义无根树中度数为1的节点是叶子节点。

    找到编号最小的叶子并删除,序列中添加与之相连的节点编号,重复执行直到只剩下2个节点。

    如下图的树对应的prufer序列就是3,5,1,3。

    具体实现可以用一个set搞定,维护度数为1的节点。复杂度O(nlogn)。

     

    (2)prufer序列转化为无根树。

    设点集V={1,2,3,...,n},每次取出prufer序列中最前面的元素u,在V中找到编号最小的没有在prufer序列中出现的元素v,给u,v连边然后分别删除,最后在V中剩下两个节点,给它们连边。最终得到的就是无根树。

    具体实现也可以用一个set,维护prufer序列中没有出现的编号。复杂度O(nlogn)。

     

    最后有一个很重要的性质就是prufer序列中某个编号出现的次数就等于这个编号的节点在无根树中的度数-1。

    接下来就是按照这个式子计算即可,用java计算会比较方便。

     2 
     3 import java.math.*;
     4 import java.util.Scanner;
     5 
     6 public class Main{
     7     static int n;
     8     static int d[]=new int[1005];
     9     static BigInteger c[]=new BigInteger[1005];
    10     static BigInteger ans;
    11     
    12     public static void main(String[] args){
    13         Scanner in=new Scanner(System.in);
    14         int flag=0, tot=0, cnt=0;
    15         while(in.hasNextInt()){
    16             n=in.nextInt();
    17             for(int i=0;i<n;i++){
    18                 d[i]=in.nextInt();
    19                 if(d[i]==0 || d[i]>n-1)  flag=1;
    20                 if(d[i]==-1)  continue;
    21                 tot+=d[i]-1;
    22                 cnt++;
    23             }
    24             
    25             if(flag==1)   {System.out.println("0");continue;}
    26             c[0]=BigInteger.valueOf(1);
    27             for(int i=1;i<=n;i++)  c[i]=c[i-1].multiply(BigInteger.valueOf(i));
    28             ans=c[n-2];
    29             for(int i=1;i<=n-2-tot;i++)  ans=ans.multiply(BigInteger.valueOf(n-cnt));
    30             ans=ans.divide(c[n-2-tot]);
    31             for(int i=0;i<n;i++){
    32                 if(d[i]==-1)  continue;
    33                 ans=ans.divide(c[d[i]-1]);
    34             }
    35             System.out.println(ans);
    36         }
    37         in.close();
    38     }
    39 }
  • 相关阅读:
    Spring messageSource
    Spring MVC集成Tiles使用方法
    Jquery发送ajax请求以及datatype参数为text/JSON方式
    怎样使用jsp实现header和footer与网页内容的分离
    jsp:include怎么设置才能正确显示包含的页面呢
    JSP中两种include的区别
    让html文件也具体include包含的功能
    DWZ中uploadify多文件上传
    DWZ+Uploadify +JSON 多文件上传
    dwz+jquery+fileupload+springmvc实现文件上传 及图片预览
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7299871.html
Copyright © 2011-2022 走看看