zoukankan      html  css  js  c++  java
  • 洛谷P3128 [USACO15DEC]Max Flow P 题解 树上差分(点差分)

    题目链接:https://www.luogu.com.cn/problem/P3128

    题目大意:

    给定一个包含 \(n\) 个节点的树,以及 \(k\) 次操作。每次操作你需要将一条路径上的点权均加 \(1\)。求 \(k\) 次操作之后的最大点权。

    解题思路:

    树上差分(点差分)。对于一条路径的两个端点 \(u\)\(v\),设 \(p\) 是它们的LCA,设 \(p'\)\(p\) 的父节点(若 \(p\) 为根节点则 \(p' = p\))。

    开差分数组 \(d\),则 \(d[u]\)\(d[v]\) 依次加 \(1\)\(d[p]\)\(d[p']\) 依次减 \(1\)

    最后对这棵树进行差分(dfs遍历一遍即可)。

    示例程序:

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 500050;
    int n, m, pa[maxn][21], dep[maxn];
    vector<int> g[maxn];
    int d[maxn], ans;
    void dfs(int u, int p) {
        dep[u] = dep[p] + 1;
        pa[u][0] = p;
        for (int i = 1; (1<<i) <= dep[u]; i ++)
            pa[u][i] = pa[ pa[u][i-1] ][i-1];
        for (auto v : g[u])
            if (v != p)
                dfs(v, u);
    }
    int lca(int x, int y) {
        if (dep[x] < dep[y]) swap(x, y);
        for (int i = 20; i >= 0; i --) {
            if (dep[ pa[x][i] ] >= dep[y]) x = pa[x][i];
            if (x == y) return x;
        }
        for (int i = 20; i >= 0; i --) {
            if (pa[x][i] != pa[y][i]) {
                x = pa[x][i];
                y = pa[y][i];
            }
        }
        return pa[x][0];
    }
    void dfs2(int u, int p) {
        for (auto v : g[u])
            if (v != p)
               dfs2(v, u), d[u] += d[v];
    }
    int main() {
        ios::sync_with_stdio(0);
        cin >> n >> m;
        for (int i = 1; i < n; i ++) {
            int u, v;
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1, 0);
        while (m --) {
            int u, v, p;
            cin >> u >> v;
            p = lca(u, v);
            d[u] ++;
            d[v] ++;
            d[p] --;
            d[pa[p][0]] --;
        }
        dfs2(1, 0);
        for (int i = 1; i <= n; i ++)
            ans = max(ans, d[i]);
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    mysql导出存储过程、函数、视图、触发器
    通过mk-table-checksum与pt-table-sync检查不同库两张表的一致性。
    Linux内核OOM机制的详细分析
    Linux虚拟内存(VM)相关参数解析
    mysqld异常重启后,自动启动应用srm进程
    利用python多线程执行远程linux上命令
    oracle数据库时常用的操作命令
    Oralce_DDL
    Oralce_PL_SQL
    mysqlbackup备份和还原
  • 原文地址:https://www.cnblogs.com/quanjun/p/15704620.html
Copyright © 2011-2022 走看看