• POJ 3659 Cell Phone Network (树dp)


    题目链接:http://poj.org/problem?id=3659

    给你一个树形图,一个点可以覆盖他周围连接的点,让你用最少的点覆盖所有的点。

    dp[i][0]表示用i点来覆盖,dp[i][1]表示用孩子节点来覆盖,dp[i][2]表示用父节点来覆盖

    (1) dp[i][0] = min(dp[i.son][0], dp[i.son][1], dp[i.son][2])

    (2) dp[i][1] = min(dp[i.son][0], dp[i.son][1]) //特判

    (3) dp[i][2] = min(dp[i.son][0], dp[i.son][1])

    注意(2)的情况,因为i需要被覆盖,所以dp[i.son][0]至少需要取到一个。

     1 //#pragma comment(linker, "/STACK:102400000, 102400000")
     2 #include <algorithm>
     3 #include <iostream>
     4 #include <cstdlib>
     5 #include <cstring>
     6 #include <cstdio>
     7 #include <vector>
     8 #include <cmath>
     9 #include <ctime>
    10 #include <list>
    11 #include <set>
    12 #include <map>
    13 using namespace std;
    14 typedef long long LL;
    15 typedef pair <int, int> P;
    16 const int N = 1e4 + 5;
    17 int dp[N][3];
    18 struct Edge {
    19     int next, to;
    20 }edge[N << 1];
    21 int head[N], cnt;
    22 
    23 inline void add(int u, int v) {
    24     edge[cnt].next = head[u];
    25     edge[cnt].to = v;
    26     head[u] = cnt++;
    27 }
    28 
    29 void dfs(int u, int p) {
    30     dp[u][0] = 1, dp[u][1] = dp[u][2] = 0;
    31     bool flag = false;
    32     int Min = 10000;
    33     for(int i = head[u]; ~i; i = edge[i].next) {
    34         int v = edge[i].to;
    35         if(v == p)
    36             continue;
    37         dfs(v, u);
    38         dp[u][0] += min(dp[v][0], min(dp[v][1], dp[v][2]));
    39         dp[u][2] += min(dp[v][1], dp[u][0]);
    40         if(dp[v][0] <= dp[v][1]) {
    41             flag = true;
    42             dp[u][1] += dp[v][0];
    43         } else {
    44             dp[u][1] += dp[v][1];
    45             Min = min(dp[v][0] - dp[v][1], Min);
    46         }
    47     }
    48     if(!flag) //要是没取到dp[v][0]
    49         dp[u][1] += Min;
    50 }
    51 
    52 int main()
    53 {
    54     int n, u, v;
    55     while(~scanf("%d", &n)) {
    56         memset(head, -1, sizeof(head));
    57         cnt = 0;
    58         for(int i = 1; i < n; ++i) {
    59             scanf("%d %d", &u, &v);
    60             add(u, v);
    61             add(v, u);
    62         }
    63         dfs(1, -1);
    64         printf("%d
    ", min(dp[1][0], dp[1][1]));
    65     }
    66     return 0;
    67 }
  • 相关阅读:
    extjs grid renderer用法
    EventListenerList举例
    SQL语句的执行原理
    WPF操作邮箱,发送邮件
    wpf中DataGrid行色变换
    JS获取浏览器和荧屏分辨率
    将数据库的二进制字节转换成图片
    字符串操作类
    ios推送基于YII第三方组件的类库
    数组操作类
  • 原文地址:https://www.cnblogs.com/Recoder/p/5838283.html
Copyright © 2020-2023  润新知