zoukankan      html  css  js  c++  java
  • 【ZOJ月赛】【树形DP】【I.Destroy】

    【题目来源】http://acm.zju.edu.cn/onlinejudge/showContestProblem.do?problemId=4937

    【个人体会】这个题目刚开始看的时候我以为是树的中心点+最小割。但是最小割那边我很怕会超时,因此一开始就没敢打,后来发现可以使用树形DP在O(N)的级别中解决这个问题,因此思路很明确,首先是求树的中心点,然后是树形DP,总级别也是O(N),可能带点常数,但无关紧要。

    【题目解析】思路分为两块,第一块是求树的中心点,有经典的O(N)级别的算法。第二块是树形DP,DP[U]表示的是以U为根的子树中,切断所有叶子节点与根节点的联系,所要付出的那个最大边的代价。因此,对于U和U的某个儿子V,在cost[U,V]和DP(V)中选一个小的,记为min{cost[U,V], DP(V)},最后在所有的min{cost[U,V], DP(V)}中选一个max用来更新DP(U)

    【代码如下】

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <climits>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <vector>
      7 #include <deque>
      8 #include <stack>
      9 #include <queue>
     10 #include <algorithm>
     11 
     12 #define rep(i, x) for (int i = 1; i <= x; ++i)
     13 #define rept(i, x) for (int i = 0; i < x; ++i)
     14 #define pb push_back
     15 #define ppf pop_front
     16 #define mp make_pair
     17 #define pf push_front
     18 #define x first
     19 #define y second
     20 
     21 #define FILE_IO
     22 #define DEBUG
     23 
     24 using namespace std;
     25 
     26 typedef long long int64;
     27 
     28 const int Max = 10001, MAX = 1e16 + 1;
     29 
     30 struct edge
     31 {
     32     int v, c, next;
     33     int64 w;
     34 }E[Max * 2];
     35 
     36 bool hash[Max];
     37 int N, Cnt, H[Max], Root;
     38 int64 Dp[Max], up[Max], down[Max][3];
     39 
     40 void Clear()
     41 {
     42     Cnt = 0;
     43     memset(H, 0, sizeof(H));
     44     memset(up, 0, sizeof(up));
     45     memset(down, 0, sizeof(down));
     46 }
     47 
     48 int64 Treedp_Dp(int i)
     49 {
     50     if (Dp[i] != -1) return Dp[i];
     51     int64 t1 = MAX, t2 = 0;
     52     bool flag = false;
     53     for (int j = H[i], v; j; j = E[j].next)
     54     {
     55         v = E[j].v;
     56         if (!hash[v]) hash[v] = flag = true;
     57         else continue;
     58         t1 = min(Treedp_Dp(v), E[j].w), t2 = max(t2, t1);
     59     }
     60     if (!flag) return MAX;
     61     Dp[i] = t2;
     62     return t2;
     63 }
     64 
     65 void Treedp()
     66 {
     67     memset(Dp, -1, sizeof(Dp));
     68     memset(hash, 0, sizeof(hash)); hash[Root] = true;
     69     printf("%lld\n", Treedp_Dp(Root));
     70 }
     71 
     72 void Center_find()
     73 {
     74     int64 t1 = 0, t2 = MAX;
     75     for (int i = 1; i <= N; ++i)
     76     {
     77         t1 = max(up[i], down[i][1]);
     78         if (t1 < t2) t2 = t1, Root = i;
     79     }
     80 }
     81 
     82 void Center_upFind(int u, int fa, int64 dis)
     83 {
     84     if (u != fa)
     85     {
     86         up[u] = up[fa] + dis;
     87         int64 tmp = 0;
     88         if (down[fa][1] == down[u][1] + dis) tmp = down[fa][2] + dis;
     89         else tmp = down[fa][1] + dis;
     90         if (tmp > up[u]) up[u] = tmp;
     91     }
     92     for (int j = H[u], v; j; j = E[j].next)
     93     {
     94         v = E[j].v;
     95         if (hash[v]) continue;
     96         hash[v] = true;
     97         Center_upFind(v, u, E[j].c);
     98     }
     99 }
    100 
    101 void Center_downFind(int u)
    102 {
    103     for (int j = H[u], v; j; j = E[j].next)
    104     {
    105         v = E[j].v;
    106         if (hash[v]) continue;
    107         hash[v] = true;
    108         Center_downFind(v);
    109         if (down[v][1] + E[j].c > down[u][1])
    110         {
    111             down[u][2] = down[u][1];
    112             down[u][1] = down[v][1] + E[j].c;
    113         }
    114         else if (down[v][1] + E[j].c > down[u][2]) down[u][2] = down[v][1] + E[j].c;
    115     }
    116 }
    117 
    118 void Center()
    119 {
    120     memset(hash, 0, sizeof(hash)); hash[1] = true;
    121     Center_downFind(1);
    122     memset(hash, 0, sizeof(hash)); hash[1] = true;
    123     Center_upFind(1, 1, 0);
    124     Center_find();
    125 }
    126 
    127 inline void edgeAdd(int &x, int &y, int &c, int &w)
    128 {
    129     E[++ Cnt].next = H[x], H[x] = Cnt, E[Cnt].v = y, E[Cnt].c = c, E[Cnt].w = w;
    130 }
    131 
    132 void Init()
    133 {
    134     for (int i = 1, x, y, c, w; i <= N - 1; ++i)
    135     {
    136         scanf("%d%d%d%d", &x, &y, &c, &w);
    137         edgeAdd(x, y, c, w);
    138         edgeAdd(y, x, c, w);
    139     }
    140 }
    141 
    142 int main()
    143 {
    144     #ifdef FILE_IO
    145     //freopen("test.in", "r", stdin);
    146     #endif // FILE_IO
    147     while (scanf("%d", &N) != EOF)
    148     {
    149         Init();
    150         Center();
    151         Treedp();
    152         Clear();
    153     }
    154     return 0;
    155 }
  • 相关阅读:
    Pyhon数据分析20——matplotlib可视化(二)之柱状图
    程序运行正常,数据库没反应
    Redis在Linux环境下安装的常见错误
    1.1-1.4 sqoop概述及安装cdh版hadoop
    3、css边框以及其他常用样式
    3.15-3.21 hive项目实战
    2、css的存在形式及优先级
    1、css选择器
    3.11-3.14 Hive 企业使用优化2
    3.7-3.10 Hive 企业使用优化1
  • 原文地址:https://www.cnblogs.com/GXZC/p/2872253.html
Copyright © 2011-2022 走看看