zoukankan      html  css  js  c++  java
  • 【树形dp】vijos1144小胖守皇宫

    细节很精妙

    描述

    huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫。

    皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状;某些宫殿间可以互相望见。大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全天候看守,在不同的宫殿安排看守所需的费用不同。

    可是xuzhenyi手上的经费不足,无论如何也没法在每个宫殿都安置留守侍卫。

    帮助xuzhenyi布置侍卫,在看守全部宫殿的前提下,使得花费的经费最少。

    格式

    输入格式

    输入文件中数据表示一棵树,描述如下:

    第1行 n,表示树中结点的数目。

    第2行至第n+1n+1行,每行描述每个宫殿结点信息,依次为:该宫殿结点标号i(0<i le n0<i≤n),在该宫殿安置侍卫所需的经费k,该点的儿子数m,接下来m个数,分别是这个节点的m个儿子的标号r_1, r_2, cdots, r_mr1​,r2​,⋯,rm​。

    对于一个n(0 < n le 15000<n≤1500)个结点的树,结点标号在1到n之间,且标号不重复。保证经费总和不超过2^31-1231−1。

    输出格式

    输出文件仅包含一个数,为所求的最少的经费。

    题目分析

    有些细节处理真的是非常精妙。

    分析详见初涉树形dp【权最小点覆盖】vijos1144皇宫看守

     1 #include<bits/stdc++.h>
     2 const int maxn = 2003;
     3 
     4 int f[maxn][3],a[maxn],n,rt;
     5 int head[maxn],nxt[maxn<<1],edges[maxn<<1],edgeTot;
     6 bool vis[maxn];
     7 
     8 int read()
     9 {
    10     char ch = getchar();
    11     int num = 0;
    12     bool fl = 0;
    13     for (; !isdigit(ch); ch = getchar())
    14         if (ch=='-') fl = 1;
    15     for (; isdigit(ch); ch = getchar())
    16         num = (num<<1)+(num<<3)+ch-48;
    17     if (fl) num = -num;
    18     return num;
    19 }
    20 inline int min(int a, int b){return a<b?a:b;}
    21 inline int min(int a, int b, int c){int t=min(a,b);return t<c?t:c;}
    22 void addedge(int u, int v)
    23 {
    24     edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
    25     vis[v] = 1;
    26 }
    27 void dfs(int now)
    28 {
    29     int delta = 2e9;
    30     for (int i=head[now]; i!=-1; i=nxt[i])
    31     {
    32         int v = edges[i];
    33         dfs(v);
    34         f[now][0] += min(f[v][1], f[v][2]);
    35         f[now][1] += min(f[v][1], f[v][2]);
    36         delta = min(f[v][2]-f[v][1], delta);
    37         f[now][2] += min(f[v][0], f[v][1], f[v][2]);
    38     }
    39     delta = std::max(delta, 0);
    40     f[now][1] += delta;
    41 }
    42 int main()
    43 {
    44     memset(head, -1, sizeof head);
    45     n = read();
    46     for (int i=1; i<=n; i++)
    47     {
    48         int p = read(), k;
    49         f[p][2] = a[p] = read(), k = read();
    50         while (k--) addedge(p, read());
    51     }
    52     rt = 1;
    53     while (vis[rt]) rt++;
    54     dfs(rt);
    55     printf("%d
    ",min(f[rt][1], f[rt][2]));
    56     return 0;
    57 }

    END

  • 相关阅读:
    MongoDB——(转)MongoDB 运维实战总结(转)
    MongoDB——4.4版本因果一致性会话
    架构——(转)用户中心 1亿数据 如何设计(转)
    MongoDB——命令备份
    JavaScript——JavaScript 弹窗
    git rebase
    shell脚本传参选项
    tftp 服务搭建
    gerrit搭建实现代码review
    Robot framework视频和教程分享
  • 原文地址:https://www.cnblogs.com/antiquality/p/9246654.html
Copyright © 2011-2022 走看看