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

  • 相关阅读:
    Eureka集群----SpringCloud 微服务
    Eureka----SpringCloud 微服务
    SpringCloud 微服务
    yml在线格式转换工具(properties)
    Spring与Mybatis三种整合方法
    Spring缓存注解@CachePut , @CacheEvict,@CacheConfig使用
    Spring事务配置的五种方式
    Spring -- <tx:annotation-driven>注解基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)的区别。
    Spring -- <context:component-scan>使用说明
    web.xml执行顺序
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4981732.html
Copyright © 2011-2022 走看看