zoukankan      html  css  js  c++  java
  • 【BZOJ2466】树

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2466


    并不算简单的树形DP,虽然状态的设计很符合树形DP的套路。。。

    设f[x][0]表示按x且x灭,x的所有子孙均亮的最少按按钮次数,1则是x亮;g[x][0]表示不按x且x灭,x的所有子孙均亮的最少按按钮次数。

    树形DP常常设dp[x]表示x子树的最优值,若无法转移,则需要设成dp[x][k]表示x子树,附加信息为k的最优值。

    下面考虑一下转移,假如按x,那么其儿子均需灭,若不按,则其儿子均需亮;可以认为x亮是因为他和他儿子中有奇数个点被按,x灭是因为有偶数个点被按,然后就可以理解转移方程了,详见代码。

    然后别忘了对于叶子节点的处理,若x为叶子结点,则f[x][0]和g[x][1]是不可能的,因此可以设为n+1,此外还有f[x][1]=1,g[x][0]=0。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 using namespace std;
     6 
     7 const int maxn = 105;
     8 
     9 int head[maxn], eid;
    10 
    11 struct Edge {
    12     int v, next;
    13 } edge[2 * maxn];
    14 
    15 inline void insert(int u, int v) {
    16     edge[++eid].v = v;
    17     edge[eid].next = head[u];
    18     head[u] = eid;
    19 }
    20 
    21 int n, f[maxn][2], g[maxn][2];
    22 //f表示按,g表示不按,0表示灭,1表示亮,而该点所有子孙均亮(如果有)的最少按按钮次数
    23 
    24 void dfs(int u, int fa) {
    25     f[u][0] = g[u][1] = n + 1, f[u][1] = 1, g[u][0] = 0;
    26     //对于叶子结点的处理
    27     for (int p = head[u]; p; p = edge[p].next) {
    28         int v = edge[p].v;
    29         if (v == fa) continue;
    30         dfs(v, u);
    31         int f0 = f[u][0], f1 = f[u][1], g0 = g[u][0], g1 = g[u][1];
    32         f[u][0] = min(f0 + g[v][0], f1 + f[v][0]);
    33         f[u][1] = min(f0 + f[v][0], f1 + g[v][0]);
    34         g[u][0] = min(g0 + g[v][1], g1 + f[v][1]);
    35         g[u][1] = min(g0 + f[v][1], g1 + g[v][1]);
    36     }
    37 }
    38 
    39 int main() {
    40     while (1) {
    41         scanf("%d", &n);
    42         if (!n) return 0;
    43         memset(head, 0, sizeof(head));
    44         eid = 0;
    45         for (int i = 1; i < n; ++i) {
    46             int u, v;
    47             scanf("%d%d", &u, &v);
    48             insert(u, v);
    49             insert(v, u);
    50         }
    51         dfs(1, 0);
    52         printf("%d
    ", min(f[1][1], g[1][1]));
    53     }
    54     return 0;
    55 }
    AC代码
  • 相关阅读:
    一sqlite分页 语句,
    array调用排序,返回的数组要 重新赋值,
    sublime text3快速编辑选中多行
    sublime text3实现多行快速编辑Ctrl+E或者Tab
    sublime使用Markdown Preview标记语言
    解决sublime package control 出现There are no packages available for installation
    sublime text 3安装html-css-js prettify后使用时报错An unhandled OS error was encountered
    sublime格式化插件---HTML-CSS-JS Prettify美化代码
    node=day5
    封装异步API
  • 原文地址:https://www.cnblogs.com/Mr94Kevin/p/9895921.html
Copyright © 2011-2022 走看看