zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    安卓学习第12课——SimpleAdapter
    用栈结构实现多项式计算器
    用B-树实现虚拟图书管理系统
    HDU4791【杂】
    HDU4801【DFS】
    萌新学习图的强连通(Tarjan算法)笔记
    Lightoj 1021【状压DP(未搞)】
    Lightoj 1008【规律】
    CodeForces Canada Cup 2016【A,B,C,D】
    51nod 1068【简单博弈】
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4981732.html
Copyright © 2011-2022 走看看