zoukankan      html  css  js  c++  java
  • [2015hdu多校联赛补题]hdu5378 Leader in Tree Land

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5378

    题意:给你一棵n个结点的有根树。因为是有根树,那么每个结点可以指定以它为根的子树(后面讨论的子树都是这个)。现在我们把标号从1到n的n个minister派驻到这些结点上面(每个结点派驻一人),并规定任一子树中编号最大的minister 为该子树的领导,问你存在多少个不同的领导

    解:

    引用官方题解:

    可以用求概率的思想来解决这个问题。令以i号节点为根的子树为第i棵子树,设这颗子树恰好有sz[i]个点。那么第i个点是第i棵子树最大值的概率为1/sz[i],不是最大值的概率为(sz[i]-1)/sz[i]。现在可以求解恰好有k个最大值的概率。
    
    令dp[i][j]表示考虑编号从1到i的点,其中恰好有j个点是其子树最大值的概率。 很容易得到如下转移方程:dp[i][j]=dp[i-1][j]*(sz[i]-1)/sz[i]+dp[i-1][j-1]/sz[i]。这样dp[n][k]就是所有点中恰好有k个最大值的概率。
    
    题目要求的是方案数,用总数n!乘上概率就是答案。计算的时候用逆元代替上面的分数即可
    
     1 /*
     2  * Problem: hdu5378  Leader in Tree Land
     3  * Author:  SHJWUDP
     4  * Created Time:  2015/8/12 星期三 20:17:31
     5  * File Name: 1006.cpp
     6  * State: Accepted
     7  * Memo: 概率dp,乘法逆元
     8  */
     9 #include <iostream>
    10 #include <cstdio>
    11 #include <vector>
    12 #include <cstring>
    13 #include <algorithm>
    14 
    15 using namespace std;
    16 
    17 const int MOD=1e9+7;
    18 
    19 struct Edge {
    20     int u, v;
    21 };
    22 
    23 int n, k;
    24 vector<Edge> edges;
    25 vector<vector<int> > G;
    26 vector<int> siz, inv;    ///siz[i]*inv[i]=1(mod 1e9+7)
    27 void init() {
    28     edges.clear();
    29     G.assign(n+1, vector<int>(0));
    30     siz.resize(n+1);
    31     inv.resize(n+1);
    32 }
    33 void addEdge(int u, int v) {
    34     edges.push_back((Edge){u, v});
    35     G[u].push_back(edges.size()-1);
    36 }
    37 int pow_mod(long long x, int n, int mod) {
    38     long long res=1;
    39     while(n) {
    40         if(n & 1) res=res*x%mod;
    41         x=x*x%mod;
    42         n>>=1;
    43     }
    44     return res;
    45 }
    46 void dfs(int u, int fa) {
    47     siz[u]=1;
    48     for(int i : G[u]) {
    49         Edge & e=edges[i];
    50         if(e.v==fa) continue;
    51         dfs(e.v, u);
    52         siz[u]+=siz[e.v];
    53     }
    54 }
    55 int main() {
    56 #ifndef ONLINE_JUDGE
    57     freopen("in", "r", stdin);
    58     //freopen("out", "w", stdout);
    59 #endif
    60     int T, now=0;
    61     scanf("%d", &T);
    62     while(T--) {
    63         scanf("%d%d", &n, &k);
    64         init();
    65         for(int i=0; i<n-1; i++) {
    66             int a, b;
    67             scanf("%d%d", &a, &b);
    68             addEdge(a, b);
    69             addEdge(b, a);
    70         }
    71         dfs(1, -1);
    72         for(int i=1; i<=n; i++) inv[i]=pow_mod(siz[i], MOD-2, MOD);    //求siz[i]的乘法逆元
    73         vector<vector<long long> > f(n+1, vector<long long>(n+1, 0));
    74         f[0][0]=1;
    75         for(int i=1; i<=n; i++) {
    76             for(int j=0; j<=k; j++) {
    77                 f[i][j]+=f[i-1][j]*(siz[i]-1)%MOD*inv[i]%MOD;
    78                 if(j>0)f[i][j]+=f[i-1][j-1]*inv[i]%MOD;
    79                 f[i][j]%=MOD;
    80             }
    81         }
    82         long long ans=f[n][k];
    83         for(int i=1; i<=n; i++) {
    84             ans=(ans*i)%MOD;
    85         }
    86         printf("Case #%d: ", ++now);
    87         printf("%I64d
    ", ans);
    88     }
    89     return 0;
    90 }
    View Code
  • 相关阅读:
    Account group in ERP and its mapping relationship with CRM partner group
    错误消息Number not in interval XXX when downloading
    错误消息Form of address 0001 not designated for organization
    Algorithm类介绍(core)
    梯度下降与随机梯度下降
    反思
    绘图: matplotlib核心剖析
    ORB
    SIFT
    Harris角点
  • 原文地址:https://www.cnblogs.com/shjwudp/p/4725795.html
Copyright © 2011-2022 走看看