zoukankan      html  css  js  c++  java
  • 「LCA + 树上差分」[USACO15DEC]最大流Max Flow

    [USACO15DEC]最大流Max Flow

    原题链接 最大流Max Flow

    题目大意

    给你 (n - 1) 条边,再给你 (m) 个操作,每次操作两个数 (u, v) 表示,(u, v) 的最短路径上每个点都加上(1)

    题目题解

    树上差分的经典题 (一直想学树上差分,今天终于会了quq),我们修改时,使(power_u)++ ,(power_v)++,(power_{lca(u,v)})--,(power_{f[lca(u,v)][0]})-- 就可以了

    接下来就是代码..xx

    //#define fre yes
    
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    
    int n, m;
    const int N = 50005;
    int head[N << 1], to[N << 1], ver[N << 1];
    int f[N][22], lg[N], depth[N], power[N];
    
    int tot;
    void addedge(int x, int y) {
        ver[tot] = y;
        to[tot] = head[x];
        head[x] = tot++;
    }
    
    void dfs(int x, int fa) {
        depth[x] = depth[fa] + 1;
        f[x][0] = fa;
        for (int i = 1; (1 << i) <= depth[x]; i++) {
            f[x][i] = f[f[x][i - 1]][i - 1];
        }
    
        for (int i = head[x]; ~i; i = to[i]) {
            int v = ver[i];
            if(v != fa) {
                dfs(v, x);
            }
        }
    }
    
    int ans;
    void sum(int u, int fa) {
        for (int i = head[u]; ~i; i = to[i]) {
            int v = ver[i];
            if(v != fa) {
                sum(v, u);
                power[u] += power[v];
            }
        } ans = std::max(ans, power[u]);
    }
    
    int lca(int u, int v) {
        if(depth[u] < depth[v]) {
            std::swap(u, v);
        }
    
        while(depth[u] > depth[v]) {
            u = f[u][lg[depth[u] - depth[v]] - 1];
        }
    
        if(u == v) return u;
    
        for (int i = lg[depth[u]] - 1; i >= 0; i--) {
            if(f[u][i] != f[v][i]) {
                u = f[u][i];
                v = f[v][i];
            }
        } return f[u][0];
    }
    
    int main() {
        memset(head, -1, sizeof(head));
        scanf("%d %d", &n, &m);
        for (int i = 1; i <= n - 1; i++) {
            int u, v;
            scanf("%d %d", &u, &v);
            addedge(u, v);
            addedge(v, u);
        }
    
        dfs(1, -1);
    
        for (int i = 1; i <= n; i++) {
            lg[i] = lg[i - 1] + (1 << lg[i - 1] == i);
        }
    
        for (int i = 1; i <= m; i++) {
            int x, y;
            scanf("%d %d", &x, &y);
            int lc = lca(x, y);
            ++power[x]; ++power[y]; --power[lc]; --power[f[lc][0]];
        }
    
        sum(1, -1);
    
        printf("%d
    ", ans);
        return 0;
    }
    
    
  • 相关阅读:
    .net知识和学习方法系列(二十)CLR委托
    Asp.net用户管理API的应用(上)
    .net知识和学习方法系列(十七)CLRCLR中的值类型和引用类型
    .net知识和学习方法系列(十九)CLR事件
    Internet Explorer 8 Beta2 常见问题解答
    关于设计模式
    Extjs中ComboBox加载并赋初值
    WPF获取窗体元素
    Extjs使用extend(js继承)
    Extjs解决上传图片预览
  • 原文地址:https://www.cnblogs.com/Nicoppa/p/11485748.html
Copyright © 2011-2022 走看看