【USACO15DEC】最大流Max Flow

题面

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

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

分析

树上点差分模板。

代码

  1. #include<bits/stdc++.h>  
  2. using namespace std;  
  3. #define N 500050  
  4. int n,m,cnt,ans;  
  5. int c[N],fa[N][20],dep[N],first[N];  
  6. struct email  
  7. {  
  8.     int u,v;  
  9.     int nxt;  
  10. }e[N*4];  
  11. template<class T>  
  12. inline void read(T &x)  
  13. {  
  14.     x=0;int f=1;static char c=getchar();   
  15.     while(c<'0'||c>'9') {if(c=='-')f=-1;c=getchar();}  
  16.     while(c>='0'&&c<='9'){x=x*10+c-'0',c=getchar();}  
  17.     x*=f;  
  18. }  
  19.   
  20. inline void add(int u,int v)  
  21. {  
  22.     e[++cnt].nxt=first[u];first[u]=cnt;  
  23.     e[cnt].u=u;e[cnt].v=v;  
  24. }  
  25.   
  26. inline void pre(int u,int f)  
  27. {  
  28.     for(int i=1;(1<<i)<=dep[u];i++)  
  29.         fa[u][i]=fa[fa[u][i-1]][i-1];  
  30.     for(int i=first[u];i;i=e[i].nxt)  
  31.     {  
  32.         int v=e[i].v;  
  33.         if(v==f)continue;  
  34.         dep[v]=dep[u]+1;  
  35.         fa[v][0]=u;  
  36.         pre(v,u);  
  37.     }     
  38. }  
  39.   
  40. inline int lca(int x,int y)  
  41. {  
  42.     if(dep[x]<dep[y])swap(x,y);  
  43.     int t=dep[x]-dep[y];  
  44.     for(int i=0;(1<<i)<=t;i++)  
  45.         if((1<<i)&t)  
  46.             x=fa[x][i];  
  47.     if(x==y)return x;  
  48.     for(int i=19;i>=0;i--)  
  49.         if(fa[x][i]!=fa[y][i])  
  50.             x=fa[x][i],y=fa[y][i];  
  51.     return fa[x][0];  
  52. }  
  53.   
  54. inline void dfs(int u,int f)  
  55. {  
  56.     for(int i=first[u];i;i=e[i].nxt)  
  57.     {  
  58.         int v=e[i].v;  
  59.         if(v==f)continue;  
  60.         dfs(v,u);  
  61.         c[u]+=c[v];  
  62.     }  
  63.     ans=max(ans,c[u]);  
  64. }  
  65.   
  66. int main()  
  67. {  
  68.     read(n),read(m);  
  69.     for(int i=1;i<n;i++)  
  70.     {  
  71.         int u,v;  
  72.         read(u),read(v);  
  73.         add(u,v);add(v,u);  
  74.     }  
  75.     pre(1,0);  
  76.     for(int i=1;i<=m;i++)  
  77.     {  
  78.         int s,t;  
  79.         read(s),read(t);  
  80.         c[s]++,c[t]++,c[lca(s,t)]--,c[fa[lca(s,t)][0]]--;  
  81.     }  
  82.     dfs(1,0);  
  83.     printf("%d\n",ans);  
  84.     return 0;  
  85.       
  86. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

若♡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值