luogu P3128 [USACO15DEC]Max Flow

题目链接: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;
}
上一篇:第十章 对象和类


下一篇:Hystrix概念设计