• luogu P3128 [USACO15DEC]Max Flow


    题目链接:luogu P3128 [USACO15DEC]Max Flow

    题目大意:

    题解:
    用树上差分来统计,点的差分与边的差分有所不同,对于\(u\)\(v\)之间的路径上的点权都加\(1\),用差分数组表示就是\(diff[u]+1, diff[v]+1, diff[lca(u,v)]-1, diff[fa[lca(u,v)][0]]-1\)

    #include <iostream>
    using namespace std;
    
    int head[50010], cnt;
    struct Edge {
        int v, next;
    } edge[100010];
    
    void addEdge(int u, int v) {
        edge[++cnt].v = v;
        edge[cnt].next = head[u];
        head[u] = cnt;
    }
    
    int n, k, ans, fa[50010][25], depth[50010];
    int diff[50010];
    
    void dfs(int u, int pre) {
        depth[u] = depth[pre] + 1;
        for (int i = 1; (1 << i) <= depth[u]; ++i) {
            fa[u][i] = fa[fa[u][i - 1]][i - 1];
        }
        for (int i = head[u]; i; i = edge[i].next) {
            int v = edge[i].v;
            if (v != pre) {
                fa[v][0] = u;
                dfs(v, u);
            }
        }
    }
    
    int lca(int u, int v) {
        if (depth[u] > depth[v]) {
            swap(u, v);
        }
        for (int i = 20; i >= 0; --i) {
            if (depth[u] <= depth[v] - (1 << i)) {
                v = fa[v][i];
            }
        }
        if (u == v) {
            return u;
        }
        for (int i = 20; i >= 0; --i) {
            if (fa[u][i] != fa[v][i]) {
                u = fa[u][i], v = fa[v][i];
            }
        }
        return fa[u][0];
    }
    
    void getSum(int u, int pre) {
        for (int i = head[u]; i; i = edge[i].next) {
            int v = edge[i].v;
            if (v != pre) {
                getSum(v, u);
                diff[u] += diff[v];
            }
        }
        ans = max(ans, diff[u]);
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin >> n >> k;
        for (int i = 1; i < n; ++i) {
            int u, v;
            cin >> u >> v;
            addEdge(u, v);
            addEdge(v, u);
        }
        dfs(1, 0);
        for (int i = 0; i < k; i++) {
            int u, v;
            cin >> u >> v;
            int Lca = lca(u, v);
            diff[u]++;
            diff[v]++;
            diff[Lca]--;
            diff[fa[Lca][0]]--;
        }
        getSum(1, 0);
        cout << ans << endl;
        return 0;
    }
    
  • 相关阅读:
    Apache虚拟主机(VirtualHost)配置
    LAMP源码安装
    SUSE上配置SAMBA服务
    Linux下安装或升级Python 2.7
    HTML5,CSS3,JS绘制饼图
    Single Number
    Reverse Words in a String
    C++控制台日历
    百度JS破盗链
    腾讯前端突击队Ⅱ
  • 原文地址:https://www.cnblogs.com/IzumiSagiri/p/15860381.html
Copyright © 2020-2023  润新知