M_sea

洛谷3128 最大流Max Flow
题目描述FJ给他的牛棚的N(2≤N≤50,000)个隔间之间安装了N-1根管道,隔间编号从1到N。所有隔间都被管道...
扫描右侧二维码阅读全文
06
2018/08

洛谷3128 最大流Max Flow

题目描述

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

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

传送门

算法

这题虽然叫最大流,然而跟网络流一点关系都没有。

按照树上差分基本套路搞搞就好了。

细节见代码。

代码

#include <bits/stdc++.h>
#define re register
using namespace std;

inline int read() {
    int X=0,w=1; char c=getchar();
    while (c<'0'||c>'9') { if (c=='-') w=-1; c=getchar(); }
    while (c>='0'&&c<='9') X=(X<<3)+(X<<1)+c-'0',c=getchar();
    return X*w;
}

struct Edge { int v,nxt; };
Edge e[100010];
int head[50010],cnt=0;

inline void addEdge(int u,int v) {
    e[++cnt].v=v;
    e[cnt].nxt=head[u];
    head[u]=cnt;
}

int dep[50010];
int f[50010][30];

inline void Dfs1(int u,int fa) {
    dep[u]=dep[fa]+1; f[u][0]=fa;
    for (re int i=1;(1<<i)<=dep[u];i++)
        f[u][i]=f[f[u][i-1]][i-1];
    for (re int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if (v!=fa) Dfs1(v,u);
    }
}

inline int LCA(int a,int b) {
    if (dep[a]<dep[b]) swap(a,b);
    for (re int i=28;~i;i--)
        if (dep[f[a][i]]>dep[b]) a=f[a][i];
    if (dep[a]!=dep[b]) a=f[a][0];
    for (re int i=28;~i;i--)
        if (f[a][i]!=f[b][i]) a=f[a][i],b=f[b][i];
    if (a!=b) a=f[a][0],b=f[b][0];
    return a;
}

int s[50010];
int ans=-1;

inline void Dfs2(int u,int fa) {
    for (re int i=head[u];i;i=e[i].nxt) {
        int v=e[i].v;
        if (v!=fa) { Dfs2(v,u); s[u]+=s[v]; }
    }
    ans=max(ans,s[u]);
}

int main() {
    int n=read(),k=read();
    for (re int i=1;i<n;i++) {
        int x=read(),y=read();
        addEdge(x,y);
        addEdge(y,x);
    }
    Dfs1(1,0);
    for (re int i=1;i<=k;i++) {
        int x=read(),y=read();
        int lca=LCA(x,y);
        s[x]++,s[y]++;
        s[lca]--,s[f[lca][0]]--;
    }
    Dfs2(1,0);
    printf("%d\n",ans);
    return 0;
}
最后修改:2018 年 11 月 09 日 05 : 03 PM

发表评论