【USACO】 Max Flow

【题目链接】

           点击打开链接

【算法】

         LCA + 树上差分

【代码】

     

#include<bits/stdc++.h>

using namespace std;

int i,x,y,N,K,l,maxn;
int anc[50010][50],d[50010],sum[50010];
vector<int> E[50010];

void build(int x,int pre) {
        int i;
        for (i = 1; i <= 20; i++) anc[x][i] = anc[anc[x][i-1]][i-1];        
        for (i = 0; i < E[x].size(); i++) {
                if (E[x][i] != pre) {
                        anc[E[x][i]][0] = x;
                        d[E[x][i]] = d[x] + 1;
                        build(E[x][i],x);
                }
        }
}

int lca(int x,int y) {
        int i,f;
        if (d[x] > d[y]) swap(x,y);
        f = d[y] - d[x];
        for (i = 0; i <= 20; i++) {
                if (f & (1 << i))
                        y = anc[y][i];
        }    
        if (x == y) return x;
        for (i = 20; i >= 0; i--) {
                if (anc[x][i] != anc[y][i]) {
                        x = anc[x][i];
                        y = anc[y][i];
                }
        }
        return anc[x][0];
}

void query(int x,int pre) {
        int i;
        for (i = 0; i < E[x].size(); i++) {
                if (E[x][i] != pre) {
                        query(E[x][i],x);
                        sum[x] += sum[E[x][i]];
                }
        }    
        maxn = max(maxn,sum[x]);
}

int main() {
    
        cin >> N >> K;
        for (i = 1; i < N; i++) {
                cin >> x >> y;
                E[x].push_back(y);
                E[y].push_back(x);
        }
        
        build(1,0);
        
        for (i = 1; i <= K; i++) {
                cin >> x >> y;
                l = lca(x,y);
                sum[x]++; sum[y]++;
                sum[l]--;
                if (anc[l][0]) sum[anc[l][0]]--;        
        }
        
        query(1,0);
        
        cout<< maxn << endl;
        
        return 0;
}

 

posted @ 2018-02-14 15:00  evenbao  阅读(167)  评论(0编辑  收藏  举报