zoukankan      html  css  js  c++  java
  • Codeforces Round #196 (Div. 1) B. Book of Evil 树形DP

    链接:

    http://codeforces.com/contest/338/problem/B

    题意:

    给出一棵树,给出感染物的感染范围,给出一些已经确定被感染的点,问感染物可能放置的点的个数。

    题解:

    定义状态dp[i]代表某个点到达离它最远的确定的感染点的距离。

    然后我们首先dfs一遍,求得以1为根的树,每个点到子树中的感染点的最大距离,然后再dfs一遍,求得dp[i]所要求的值,利用一个dd[i]数组表示第i点的父亲,除了自己及以自己为根的子树的点的感染点到自己的最远距离。

    然后处理出来每个点儿子的前缀和后缀的最大值,然后利用dd就可以求取dp[i]

    代码:

     31 int n, m, d;
     32 int p[MAXN];
     33 VI G[MAXN];
     34 int dp[MAXN], dd[MAXN];
     35 int lef[MAXN], rig[MAXN];
     36 
     37 void dfs(int u, int par) {
     38     if (p[u]) dp[u] = 0;
     39     rep(i, 0, G[u].size()) {
     40         int v = G[u][i];
     41         if (v == par) continue;
     42         dfs(v, u);
     43         dp[u] = max(dp[u], dp[v] + 1);
     44     }
     45 }
     46 
     47 void dfs1(int u, int par) {
     48     lef[0] = -INF;
     49     rig[G[u].size() + 1] = -INF;
     50     rep(i, 0, G[u].size()) {
     51         int x = i + 1;
     52         int v = G[u][i];
     53         if (v == par) {
     54             lef[x] = lef[x - 1];
     55             continue;
     56         }
     57         lef[x] = max(lef[x - 1], dp[v]);
     58     }
     59     per(i, 0, G[u].size()) {
     60         int x = i + 1;
     61         int v = G[u][i];
     62         if (v == par) {
     63             rig[x] = rig[x + 1];
     64             continue;
     65         }
     66         rig[x] = max(rig[x + 1], dp[v]);
     67     }
     68     rep(i, 0, G[u].size()) {
     69         int x = i + 1;
     70         int v = G[u][i];
     71         if (v == par) continue;
     72         dd[v] = max(dd[u], max(lef[x - 1], rig[x + 1]) + 1) + 1;
     73         dp[v] = max(dp[v], dd[v]);
     74     }
     75     rep(i, 0, G[u].size()) {
     76         int v = G[u][i];
     77         if (v == par) continue;
     78         dfs1(v, u);
     79     }
     80 }
     81 
     82 int main() {
     83     ios::sync_with_stdio(false), cin.tie(0);
     84     cin >> n >> m >> d;
     85     rep(i, 0, m) {
     86         int x;
     87         cin >> x;
     88         p[x] = 1;
     89     }
     90     rep(i, 1, n) {
     91         int u, v;
     92         cin >> u >> v;
     93         G[u].pb(v);
     94         G[v].pb(u);
     95     }
     96     memset(dp, -0x3f, sizeof(dp));
     97     memset(dd, -0x3f, sizeof(dd));
     98     dfs(1, -1);
     99     if (p[1]) dd[1] = 0;
    100     dfs1(1, -1);
    101     int ans = 0;
    102     rep(i, 1, n + 1) if (dp[i] >= 0 && dp[i] <= d) ans++;
    103     cout << ans << endl;
    104     return 0;
    105 }
  • 相关阅读:
    npm WARN saveError ENOENT: no such file or directory的解决方法
    简单的webpack打包案例
    JS中用encodeURIComponent编码,后台JAVA解码
    说 Redis
    let the cat out of the bag
    简述C# volatile 关键字
    螃蟹怎么分公母?是用冷水上锅还是热水蒸呢?
    Mysql截取字符串 更新字段的部分内容
    Ajax 获取数据attr后获取不到
    如何限制域名访问?白名单机制
  • 原文地址:https://www.cnblogs.com/baocong/p/7339033.html
Copyright © 2011-2022 走看看