zoukankan      html  css  js  c++  java
  • [HNOI2004][bzoj1211] 树的计数(prufer序列)

    1211: [HNOI2004]树的计数

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 3432  Solved: 1295
    [Submit][Status][Discuss]

    Description

    一个有n个结点的树,设它的结点分别为v1, v2, …, vn,已知第i个结点vi的度数为di,问满足这样的条件的不同的树有多少棵。给定n,d1, d2, …, dn,编程需要输出满足d(vi)=di的树的个数。

    Input

    第一行是一个正整数n,表示树有n个结点。第二行有n个数,第i个数表示di,即树的第i个结点的度数。其中1<=n<=150,输入数据保证满足条件的树不超过10^17个。

    Output

    输出满足条件的树有多少棵。

    Sample Input

    4
    2 1 2 1

    Sample Output

    2

    题解:

    果的prufer序列计数,关于prufer序列的性质(戳这里[HNOI2008] 明明的烦恼)。

    知道了prufer序列的性质这题也就迎刃而解了,这不就是求不全相异全排列个数嘛,直接套式子

    $frac{left ( n - 2 ight )!}{prod left ( d[i] - 1  ight )! }$

    还是hin简单的趴

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<vector>
     6 #include<queue>
     7 using namespace std;
     8 int d[205];
     9 struct node{
    10     int m[500005];
    11     friend void operator *= (node &a,int b){
    12         int x=0;
    13         for(int i=1;i<=a.m[0];i++){
    14             int y=a.m[i]*b+x;
    15             a.m[i]=y%10;
    16             x=y/10;
    17         }
    18         while(x){
    19             a.m[++a.m[0]]=x%10;
    20             x/=10;
    21         }
    22     }
    23     friend void operator /= (node &a,int b){
    24         int x=0;
    25         for(int i=a.m[0];i>=1;i--){
    26             x+=a.m[i];
    27             a.m[i]=x/b;
    28             x%=b;
    29             x*=10;
    30         }
    31         while(a.m[a.m[0]]==0&&a.m[0]>1) a.m[0]--;
    32     }
    33     friend void print(node a){
    34         for(int i=a.m[0];i>=1;i--) printf("%d",a.m[i]);
    35         puts("");
    36     }
    37 }ans;
    38 int main(){
    39     int n,m;
    40     scanf("%d",&n);
    41     int sum=0;
    42     ans.m[0]=ans.m[1]=1;
    43     for(int i=1;i<=n;i++){
    44         scanf("%d",&d[i]);
    45         if(!d[i]&&n!=1){puts("0");return 0;}
    46         d[i]--;
    47         sum+=d[i];
    48     }
    49     if(sum!=n-2){puts("0");return 0;}
    50     for(int i=1;i<=n-2;i++) ans*=i;
    51     //print(ans);
    52     for(int i=1;i<=n;i++){
    53         if(d[i]>0){
    54             for(int j=1;j<=d[i];j++) ans/=j;
    55         }
    56     }
    57     print(ans);
    58 }
    View Code
  • 相关阅读:
    数据库练习
    数据库的设计范式知识
    asserts文件存到外部SD卡里
    用户的注册信息存储到文件里,登录成功后读出并显示出来
    java快速排序引起的StackOverflowError异常
    并发入库面临重复数据的问题
    《旅行青蛙》安卓版本修改钱和奖券
    ddmlib问题总结——同步获取设备信息
    Java ArrayList中对象的排序 (Comparable VS Comparator)
    Authentication(Spring Security 认证笔记)
  • 原文地址:https://www.cnblogs.com/leom10/p/11235597.html
Copyright © 2011-2022 走看看