zoukankan      html  css  js  c++  java
  • UVALive 7148 LRIP 14年上海区域赛K题 树分治

    题意 n个点组成一棵树, 带有点权。 求最长不降的路径的长度, 且路径上最大值最小值之差不超过D。

    显然是树分治, 但是分治之后如何维护答案呢。

    假设当前重心为g, 分别记录g出发不降路径的长度,以及最大值, 和不升路径的长度以及最小值。

    这里用到一个map和二分, 线段树也可以, 但是如果用线段树还要考虑负值, 再加上线段树的clear以及稍微暴力的查询。  常数大小不好说。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 typedef pair <int, int> pii;
      4 const int maxn = 1e5 + 5;
      5 vector <int> G[maxn];
      6 int val[maxn], siz[maxn], n, D;
      7 bool centroid[maxn];
      8 void init() {
      9     for (int i = 0; i < maxn; i++) {
     10         G[i].clear();
     11     }
     12     memset(centroid, false, sizeof centroid);
     13 }
     14 void dfs(int u, int father){
     15     siz[u] = 1;
     16     for (int v: G[u]){
     17         if (v != father && !centroid[v]){
     18             dfs(v, u);
     19             siz[u] += siz[v];
     20         }
     21     }
     22 }
     23 pii FindCentroid(int u, int father, int t) {
     24     pii res = make_pair(INT_MAX, -1);
     25     int s = 1, m  = 0;
     26     for (int v: G[u]) {
     27         if (v == father || centroid[v]) {
     28             continue;
     29         }
     30         res = min(res, FindCentroid(v, u, t));
     31         m = max(m, siz[v]);
     32         s += siz[v];
     33     }
     34     siz[u] = s;
     35     m = max(m, t-s);
     36     return min(res, make_pair(m, u));
     37 }
     38 map <int, int> work;
     39 void update(int v, int len) {
     40     auto it = work.lower_bound(v);
     41     if (it != work.end() && it->second >= len) {
     42         return;
     43     }
     44     work[v] = len;
     45 }
     46 void dfs_up(int u, int father, int d) {
     47     if (val[u] > val[father]) {
     48         return;
     49     }
     50     update(val[u], d);
     51     for (int v: G[u]) {
     52         if (v != father && !centroid[v]) {
     53             dfs_up(v, u, d+1);
     54         }
     55     }
     56 }
     57 int res;
     58 void dfs_down(int u, int father, int d) {
     59     if (val[u] < val[father]) {
     60         return;
     61     }
     62     auto it = work.lower_bound(val[u]-D);
     63     if (it != work.end()) {
     64         res = max(res, it->second+1+d);
     65     }
     66     for (int v: G[u]) {
     67         if (!centroid[v] && v != father) {
     68             dfs_down(v, u, d+1);
     69         }
     70     }
     71 }
     72 
     73 void preSolve(int g, vector <int> &son) {
     74     work.clear();
     75     work[val[g]] = 0;
     76     for (int v: son) {
     77         if (val[v] >= val[g]) {
     78             dfs_down(v, g, 1);
     79         }
     80         if (val[v] <= val[g]) {
     81             dfs_up(v, g, 1);
     82         }
     83     }
     84 }
     85 void solve(int u) {
     86     dfs(u, 0);
     87     int g = FindCentroid(u, 0, siz[u]).second;
     88     vector <int> son;
     89     for (int v: G[g]) {
     90         if (!centroid[v]) {
     91             son.push_back(v);
     92         }
     93     }
     94     preSolve(g, son);
     95     reverse(son.begin(), son.end());
     96     preSolve(g, son);
     97     centroid[g] = true;
     98     for (int v: G[g]) {
     99         if (!centroid[v]) {
    100             solve(v);
    101         }
    102     }
    103 }
    104 int main() {
    105    // freopen("in.txt", "r", stdin);
    106     int T, cas = 1;
    107     scanf ("%d", &T);
    108     while (T--) {
    109         init();
    110         scanf ("%d%d", &n, &D);
    111         for (int i = 1; i <= n; i++) {
    112             scanf ("%d", val+i);
    113         }
    114         for (int i = 1; i < n; i++) {
    115             int u, v;
    116             scanf ("%d%d", &u, &v);
    117             G[u].push_back(v);
    118             G[v].push_back(u);
    119         }
    120         res = 1;
    121         solve(1);
    122         printf("Case #%d: %d
    ", cas++, res);
    123     }
    124     return 0;
    125 }
  • 相关阅读:
    笔记:2016-06-20
    笔记2016-06-22
    javascript中的call(),apply(),bind()方法的区别
    JavaScript实现大整数减法
    Javascript实现大整数加法
    Javascript toString()、toLocaleString()、valueOf()三个方法的区别
    排序算法时间空间复杂度比较
    H-ui框架制作选项卡
    es6 解构赋值
    fullPage全屏高度自适应
  • 原文地址:https://www.cnblogs.com/oneshot/p/5001967.html
Copyright © 2011-2022 走看看