• BZOJ 2314: 士兵的放置( 树形dp )


    树形dp...

    dp(x, 0)表示结点x不放士兵, 由父亲控制;

    dp(x, 1)表示结点x不放士兵, 由儿子控制;

    dp(x, 2)表示结点x放士兵. 

    -------------------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
     
    using namespace std;
     
    typedef long long ll;
     
    const int maxn = 500009;
    const int MOD = 1032992941;
     
    struct edge {
    int to;
    edge* next;
    } E[maxn << 1], *pt = E, *head[maxn];
     
    void AddEdge(int u, int v) {
    pt->to = v; pt->next = head[u]; head[u] = pt++;
    }
     
    void upd0(ll &x, int t) {
    if((x += t) >= MOD) x -= MOD;
    }
     
    void upd1(ll &x, int t) {
    x = x * t % MOD;
    }
     
    int N;
    ll dp[maxn][3], cnt[maxn][3];
     
    void init() {
    scanf("%d", &N);
    for(int i = 1; i < N; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    AddEdge(--u, --v);
    AddEdge(v, u);
    }
    }
     
    void dfs(int x, int fa) {
    dp[x][0] = 0; dp[x][1] = maxn; dp[x][2] = 1;
    cnt[x][0] = cnt[x][1] = cnt[x][2] = 1;
    ll Min, sum;
    for(edge* e = head[x]; e; e = e->next) if(e->to != fa) {
    dfs(e->to, x);
    Min = min(min(dp[e->to][0], dp[e->to][1]), dp[e->to][2]);
    sum = 0;
    dp[x][2] += Min;
    for(int i = 0; i < 3; i++)
    if(dp[e->to][i] == Min) upd0(sum, cnt[e->to][i]);
    upd1(cnt[x][2], sum);
    Min = min(dp[x][1] + min(dp[e->to][1], dp[e->to][2]), dp[x][0] + dp[e->to][2]);
    sum = 0;
    for(int i = 1; i < 3; i++) 
    if(dp[x][1] + dp[e->to][i] == Min) upd0(sum, cnt[e->to][i]);
    upd1(cnt[x][1], sum);
    if(dp[x][0] + dp[e->to][2] == Min)
    upd0(cnt[x][1], ll(cnt[x][0]) * cnt[e->to][2] % MOD);
    dp[x][1] = Min;
    dp[x][0] += dp[e->to][1];
    upd1(cnt[x][0], cnt[e->to][1]);
    }
    }
     
    int main() {
    init();
    dfs(0, -1);
    ll ans = min(dp[0][1], dp[0][2]), sum = 0;
    for(int i = 1; i < 3; i++)
    if(dp[0][i] == ans) upd0(sum, cnt[0][i]);
    printf("%lld %lld ", ans, sum);
    return 0;
    }

    -------------------------------------------------------------------------------------

    2314: 士兵的放置

    Time Limit: 20 Sec  Memory Limit: 512 MB
    Submit: 114  Solved: 31
    [Submit][Status][Discuss]

    Description


    八中有N个房间和N-1双向通道,任意两个房间均可到达.现在出了一件极BT的事,就是八中开始闹鬼了。老大决定加强安保,现在如果在某个房间中放一个士兵,则这个房间以及所有与这个房间相连的房间都会被控制.现在

    老大想知道至少要多少士兵可以控制所有房间.以及有多少种不同的方案数. 

    Input

     

    第一行一个数字N,代表有N个房间,房间编号从1开始到N.N<=500000,下面将有N-1行,每行两个数,代表这两个房间相连. 

    Output

    第一行输出至少有多少个士兵才可以控制所有房间第二行输出有多少种方案数,方案数会比较大,输出除以1032992941的余数吧. 

    Sample Input

    6
    1 2
    1 3
    1 5
    1 4
    5 6

    Sample Output

    2
    2


    HINT

    第一种方案是将士兵放在1号房间及6号房间 

    第二种方案是将士兵放在1号房间及5号房间 

    Source

  • 相关阅读:
    TransactionScope和Enterprise Libray 3.0 Data Access Application Block
    C#之父 Anders Hejlsberg
    openSUSE Linux 10.2 多语言版
    承蒙各位朋友支持与厚爱,荣获asp.net MVP荣誉
    如何在ASP.NET 2.0中定制Expression Builders
    检查Python对象
    IronPython中使用Cecil类库指南
    MSDN Magazine 4月份asp.net文章
    Reflector 插件
    WSS v3的Form身份认证
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4981732.html
Copyright © 2020-2023  润新知