洛谷P3128 [USACO15DEC]最大流Max Flow

洛谷P3128 [USACO15DEC]最大流Max Flow

题目描述

FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道连通了。

FJ有K(1≤K≤100,000)条运输牛奶的路线,第i条路线从隔间si运输到隔间ti。一条运输路线会给它的两个端点处的隔间以及中间途径的所有隔间带来一个单位的运输压力,你需要计算压力最大的隔间的压力是多少。

输入输出格式

输入格式:

The first line of the input contains $N$ and $K$.

The next $N-1$ lines each contain two integers $x$ and $y$ ($x e y$) describing a pipe

between stalls $x$ and $y$.

The next $K$ lines each contain two integers $s$ and $t$ describing the endpoint

stalls of a path through which milk is being pumped.

输出格式:

An integer specifying the maximum amount of milk pumped through any stall in the

barn.

输入输出样例

输入样例#1: 复制
5 10
3 4
1 5
4 2
5 4
5 4
5 4
3 5
4 3
4 3
1 3
3 5
5 4
1 5
3 4
输出样例#1: 复制
9

分析

树上差分的模板题,对x->y路径上的点加,等于x->root,y->root加,lca(x,y)->root,father[lca(x,y)]->root减。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=100010;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n,k,tot;
int head[N],dep[N],f[N][20],sum[N];
struct node{
    int next,to;
}e[N*2];
inline void ins(int from,int to){
    e[++tot].next=head[from];
    e[tot].to=to; head[from]=tot;
}
void dfs(int x,int fa){
    for(int i=head[x];i;i=e[i].next)
    if(e[i].to!=fa){
        dep[e[i].to]=dep[x]+1;
        f[e[i].to][0]=x;
        dfs(e[i].to,x);
    }
}
inline int lca(int a,int b){
    if(dep[a]<dep[b]){int t=a;a=b;b=t;}
    int d=dep[a]-dep[b];
    for(int i=0;i<=18;++i)
    if(d&(1<<i)) a=f[a][i];
    if(a==b) return a;
    for(int i=18;i>=0;--i)
    if(f[a][i]!=f[b][i])
    a=f[a][i],b=f[b][i];
    return f[a][0];
}
void calc(int x){
    for(int i=head[x];i;i=e[i].next)
    if(e[i].to!=f[x][0]){
        calc(e[i].to);
        sum[x]+=sum[e[i].to];
    }
}
    
int main(){
    n=read();k=read();
    for(int i=1;i<n;++i){
        int x=read(),y=read();
        ins(x,y); ins(y,x);
    }
    dep[1]=1; dfs(1,-1);
    for(int j=1;j<=18;++j)
    for(int i=1;i<=n;++i)
    f[i][j]=f[f[i][j-1]][j-1];
    for(int i=1;i<=k;++i){
        int a=read(),b=read(),c;
        c=lca(a,b);
        ++sum[a]; ++sum[b];
        --sum[c]; --sum[f[c][0]];
    }
    calc(1);
    int ans=0;
    for(int i=1;i<=n;++i)
    ans=max(ans,sum[i]);
    printf("%d
",ans);
    return 0;
}
    
原文地址:https://www.cnblogs.com/huihao/p/7791736.html