• 2015 Multi-University Training Contest 7 hdu 5378 Leader in Tree Land


    Leader in Tree Land

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 447    Accepted Submission(s): 185

    Problem Description
    Tree land has n cities, connected by n−1 roads. You can go to any city from any city. In other words, this land is a tree. The city numbered one is the root of this tree.

    There are n ministers numbered from 1 to n. You will send them to n cities, one city with one minister.

    Since this is a rooted tree, each city is a root of a subtree and there are n subtrees. The leader of a subtree is the minister with maximal number in this subtree. As you can see, one minister can be the leader of several subtrees.

    One day all the leaders attend a meet, you find that there are exactly k ministers. You want to know how many ways to send n ministers to each city so that there are k ministers attend the meet.

    Give your answer mod $1000000007$.

    Input
    Multiple test cases. In the first line there is an integer T, indicating the number of test cases. For each test case, first line contains two numbers n,k. Next n−1 line describe the roads of tree land.

    $T=10,1 leq n leq 1000,1 leq k leq n$

    Output
    For each test case, output one line. The output format is Case #x: ans, x is the case number,starting from 1.

    Sample Input
    2
    3 2
    1 2
    1 3
    10 8
    2 1
    3 2
    4 1
    5 3
    6 1
    7 3
    8 7
    9 7
    10 6

    Sample Output
    Case #1: 4
    Case #2: 316512

    Author
    UESTC

    Source
    2015 Multi-University Training Contest 7  1010

    解题:动态规划 这位博主大牛说得非常清楚

    我们用x[i],y[i]分别代表这个节点能够成为leader和不能够成为leader的概率。

    son[i] 代表以i节点为根的子树的节点数。

    那么$x[i] = 1/son[i],y[i] = 1-(1/son[i])$。因为这里面出现了分数,所有我们用逆元处理一下。

    我们设dp[i][j]表示编号为1,2...i的节点中有j个leader的概率。

    那么转移方程就是 $dp[i][j] = dp[i-1][j-1] * x[i] + dp[i-1][j] * y[i]$。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const LL mod = 1000000007;
     5 const int maxn = 1010;
     6 struct arc {
     7     int to,next;
     8     arc(int x = 0,int y = -1) {
     9         to = x;
    10         next = y;
    11     }
    12 } e[maxn<<1];
    13 int son[maxn],head[maxn],tot;
    14 LL F[maxn] = {1},x[maxn],y[maxn],dp[maxn][maxn];
    15 void init() {
    16     for(int i = 1; i < maxn; ++i)
    17         F[i] = F[i-1]*i%mod;
    18 }
    19 void add(int u,int v) {
    20     e[tot] = arc(v,head[u]);
    21     head[u] = tot++;
    22 }
    23 LL gcd(LL a,LL b,LL &x,LL &y) { //ax + by = gcd(a,b)
    24     if(!b) {
    25         x = 1;
    26         y = 0;
    27         return a;
    28     }
    29     LL ret = gcd(b,a%b,y,x);
    30     y -= x*(a/b);
    31     return ret;
    32 }
    33 LL Inv(LL b,LL mod) { //求b % mod的逆元
    34     LL x,y,d = gcd(b,mod,x,y);
    35     return d == 1?(x%mod + mod)%mod:-1;
    36 }
    37 void dfs(int u,int fa) {
    38     son[u] = 1;
    39     for(int i = head[u]; ~i; i = e[i].next) {
    40         if(e[i].to == fa) continue;
    41         dfs(e[i].to,u);
    42         son[u] += son[e[i].to];
    43     }
    44 }
    45 int main() {
    46     int kase,n,k,u,v,cs = 1;
    47     init();
    48     scanf("%d",&kase);
    49     while(kase--) {
    50         scanf("%d%d",&n,&k);
    51         memset(head,-1,sizeof head);
    52         tot = 0;
    53         for(int i = 1; i < n; ++i) {
    54             scanf("%d%d",&u,&v);
    55             add(u,v);
    56             add(v,u);
    57         }
    58         dfs(1,-1);
    59         for(int i = 1; i <= n; ++i) {
    60             x[i] = Inv(son[i],mod);
    61             y[i] = (son[i] - 1)*x[i]%mod;
    62         }
    63         memset(dp,0,sizeof dp);
    64         dp[1][0] = y[1];
    65         dp[1][1] = x[1];
    66         for(int i = 2; i <= n; ++i) {
    67             dp[i][0] = dp[i-1][0]*y[i]%mod;
    68             for(int j = 1; j <= min(i,k); ++j) {
    69                 LL a = dp[i-1][j-1]*x[i]%mod;
    70                 LL b = dp[i-1][j]*y[i]%mod;
    71                 dp[i][j] = (a + b)%mod;
    72             }
    73         }
    74         printf("Case #%d: %I64d
    ",cs++,dp[n][k]*F[n]%mod);
    75     }
    76     return 0;
    77 }
    View Code
  • 相关阅读:
    linux 切换图形界面
    google浏览器插件源码目录查询
    subline注册码
    mongodb数组多值查询(条件:数据库中必须包含条件信息)
    SpringBoot多数据源解决方案(转载)
    腾讯云服务器做代理
    多线程经典问题顺序打印
    flume 1.7在windows下的安装部署与测试运行
    解决spring-boot-maven-plugin插件打包,springboot启动时报找不到主main问题
    MYSQL的B+Tree索引树高度如何计算
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4742059.html
Copyright © 2020-2023  润新知