[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次操作完毕后权值最大的那个点的权值。

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.

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 }

原文地址:https://www.cnblogs.com/lcxer/p/9441773.html

时间: 2024-10-10 02:38:16

[Usaco2015 dec]Max Flow的相关文章

bzoj4390: [Usaco2015 dec]Max Flow

4390: [Usaco2015 dec]Max Flow Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 139  Solved: 85[Submit][Status][Discuss] Description Farmer John has installed a new system of N−1 pipes to transport milk between the N stalls in his barn (2≤N≤50,000), co

bzoj4390: [Usaco2015 dec]Max Flow(LCA+树上差分)

题目大意:给出一棵树,n(n<=5w)个节点,k(k<=10w)次修改,每次给定s和t,把s到t的路径上的点权+1,问k次操作后最大点权. 对于每次修改,给s和t的点权+1,给lca(s,t)和lca(s,t)的父亲的点权-1,每一个点的权就是它与它的子树权和,实际上就是树上的差分,又涨姿势了... 代码如下: uses math; type point=^rec; rec=record data:longint; next:point; end; var n,m,x,y,i,ans,fa,k

bzoj4393: [Usaco2015 Dec]Fruit Feast

题意: T,A,B.T是上限.A和B可以随意吃但是不能超过T.有一次将吃的东西/2的机会.然后可以继续吃,不能超过T.问最多可以吃多少. =>我们先处理不能/2可以吃到哪些.然后弄个双指针扫一扫就可以了TAT #include<cstdio> #include<cstring> #include<cctype> #include<algorithm> using namespace std; #define rep(i,s,t) for(int i=s

洛谷 P3128 [USACO15DEC]最大流Max Flow

P3128 [USACO15DEC]最大流Max Flow 题目描述 Farmer John has installed a new system of N-1N−1 pipes to transport milk between the NN stalls in his barn (2 \leq N \leq 50,0002≤N≤50,000), conveniently numbered 1 \ldots N1…N. Each pipe connects a pair of stalls,

bzoj4397【Usaco2015 Dec】Breed Counting

4397: [Usaco2015 dec]Breed Counting Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 29  Solved: 25 [Submit][Status][Discuss] Description Farmer John's N cows, conveniently numbered 1-N, are all standing in a row (they seem to do so often that it now

洛谷P3128 [USACO15DEC]最大流Max Flow [树链剖分]

题目描述 Farmer John has installed a new system of  pipes to transport milk between the  stalls in his barn (), conveniently numbered . Each pipe connects a pair of stalls, and all stalls are connected to each-other via paths of pipes. FJ is pumping milk

bzoj4396[Usaco2015 dec]High Card Wins*

bzoj4396[Usaco2015 dec]High Card Wins 题意: 一共有2n张牌,Alice有n张,Bob有n张,每一局点数大的赢.知道Bob的出牌顺序,求Alice最多能赢几局.n≤50000. 题解: 贪心.将Alice和Bob的牌按点数大小排序,然后如果Alice当前牌能赢Bob当前牌就ans++否则就不断调整Bob的当前牌直到Alice当前牌能赢Bob当前牌. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #

bzoj4397[Usaco2015 dec]Breed Counting*

bzoj4397[Usaco2015 dec]Breed Counting 题意: 给定一个长度为N的序列,每个位置上的数只可能是1,2,3中的一种.有Q次询问,每次给定两个数a,b,请分别输出区间[a,b]里数字1,2,3的个数.n≤100000,q≤100000. 题解: 裸前缀和. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define inc(i,j,k) for

bzoj4395[Usaco2015 dec]Switching on the Lights*

bzoj4395[Usaco2015 dec]Switching on the Lights 题意: n*n个房间,奶牛初始在(1,1),且只能在亮的房间里活动.每当奶牛经过一个房间,就可以打开这个房间里控制其它房间灯的开关.问奶牛最多可点亮多少个房间.n≤100. 题解: 因为只要一个房间灯亮了,它将一直亮着,所以可以做bfs,每次由队列中的节点扩展可以到的节点.然而这样做不行,因为可能之前尝试过不能到达的房间的灯可以在之后到达的房间里被打开.解决方法是不停做bfs,直到答案不再更新. 代码: