bzoj4390:[Usaco2015 dec]Max Flow
Description
Farmer John has installed a new system of N?1 pipes to transport milk between the N stalls in his ba
rn (2≤N≤50,000), conveniently numbered 1…N. Each pipe connects a pair of stalls, and all stalls a
re connected to each-other via paths of pipes.FJ is pumping milk between KK pairs of stalls (1≤K≤1
00,000). For the iith such pair, you are told two stalls sisi and titi, endpoints of a path along wh
ich milk is being pumped at a unit rate. FJ is concerned that some stalls might end up overwhelmed w
ith all the milk being pumped through them, since a stall can serve as a waypoint along many of the
KK paths along which milk is being pumped. Please help him determine the maximum amount of milk bein
g pumped through any stall. If milk is being pumped along a path from sisi to titi, then it counts a
s being pumped through the endpoint stalls sisi and titi, as well as through every stall along the p
ath between them.
给定一棵有N个点的树,所有节点的权值都为0。
有K次操作,每次指定两个点s,t,将s到t路径上所有点的权值都加一。
请输出K次操作完毕后权值最大的那个点的权值。
rn (2≤N≤50,000), conveniently numbered 1…N. Each pipe connects a pair of stalls, and all stalls a
re connected to each-other via paths of pipes.FJ is pumping milk between KK pairs of stalls (1≤K≤1
00,000). For the iith such pair, you are told two stalls sisi and titi, endpoints of a path along wh
ich milk is being pumped at a unit rate. FJ is concerned that some stalls might end up overwhelmed w
ith all the milk being pumped through them, since a stall can serve as a waypoint along many of the
KK paths along which milk is being pumped. Please help him determine the maximum amount of milk bein
g pumped through any stall. If milk is being pumped along a path from sisi to titi, then it counts a
s being pumped through the endpoint stalls sisi and titi, as well as through every stall along the p
ath between them.
给定一棵有N个点的树,所有节点的权值都为0。
有K次操作,每次指定两个点s,t,将s到t路径上所有点的权值都加一。
请输出K次操作完毕后权值最大的那个点的权值。
Input
The first line of the input contains NN and KK.
The next N-1 lines each contain two integers x and y (x≠y,x≠y) describing a pipe between stalls x and y.
The next K lines each contain two integers ss and t describing the endpoint stalls of a path through which milk is being pumped.
The next N-1 lines each contain two integers x and y (x≠y,x≠y) describing a pipe between stalls x and y.
The next K lines each contain two integers ss and t describing the endpoint stalls of a path through which milk is being pumped.
Output
An integer specifying the maximum amount of milk pumped through any stall in the barn.
Sample Input
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
Sample Output
9
树上差分,这是一道模板题,思路和普通的差分是一样的,就是需要在一棵树上进行差分的操作
那么,肯定的是s和t到他们的最近公共祖先的路径上的点的边权都是要加1的,那么就可以做
sum[s]++,sum[t]++,sum[lca(s,t)]--;
但是如果lca(s,t)不是根节点那么sum[father[lca(s,t)]]--,因为我们在加的时候s和t一共加了
两遍,所以需要把sum[lca(s,t)]--,把sum[father[lca(s,t)]]--就不用我说了吧,学过差分的都知道,如果没学过就没必要来看这个了。
代码:
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 int son[100001],nex[100001],ans,pre[100001],fa[100001],f[100001][20],n,m,a,b,root,tot,sum[100001],father[100001],now[100001],deep[100001]; 5 void add(int x,int y) 6 { 7 tot++; 8 son[tot]=y; 9 nex[tot]=pre[x]; 10 pre[x]=tot; 11 } 12 void dfs(int now,int fa) 13 { 14 father[now]=fa; 15 for(int i=1;i<=19;i++) 16 { 17 if(deep[now]<(1<<i))break; 18 f[now][i]=f[f[now][i-1]][i-1]; 19 } 20 for(int i=pre[now];i;i=nex[i]) 21 if(son[i]!=fa) 22 { 23 int k=son[i]; 24 deep[k]=deep[now]+1; 25 f[k][0]=now; 26 dfs(k,now); 27 } 28 } 29 int lca(int x,int y) 30 { 31 if(deep[x]>deep[y])swap(x,y); 32 int poor=deep[y]-deep[x]; 33 for(int i=0;i<=19;i++) 34 if((1<<i)&poor) 35 y=f[y][i]; 36 for(int i=19;i>=0;i--) 37 if(f[x][i]!=f[y][i]) 38 x=f[x][i],y=f[y][i]; 39 if(x==y)return x; 40 return f[x][0]; 41 } 42 void get(int x,int fa) 43 { 44 now[x]=sum[x]; 45 for(int i=pre[x];i;i=nex[i]) 46 if(son[i]!=fa) 47 { 48 get(son[i],x); 49 now[x]+=now[son[i]]; 50 } 51 ans=max(ans,now[x]); 52 } 53 int main() 54 { 55 scanf("%d%d",&n,&m); 56 for(int i=1;i<n;i++) 57 scanf("%d%d",&a,&b),add(a,b),add(b,a); 58 dfs(1,0); 59 int begin,end; 60 for(int i=1;i<=m;i++) 61 { 62 scanf("%d%d",&begin,&end); 63 int r=lca(begin,end); 64 sum[begin]++,sum[end]++,sum[r]--; 65 if(r!=1)sum[father[r]]--; 66 } 67 get(1,0); 68 printf("%d",ans); 69 }