BZOJ4390: [Usaco2015 dec]Max Flow
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 barn (2≤N≤50,000), conveniently numbered 1…N. Each pipe connects a pair of stalls, and all stalls are connected to each-other via paths of pipes.
FJ is pumping milk between KK pairs of stalls (1≤K≤100,000). For the iith such pair, you are told two stalls sisi and titi, endpoints of a path along which milk is being pumped at a unit rate. FJ is concerned that some stalls might end up overwhelmed with 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 being pumped through any stall. If milk is being pumped along a path from sisi to titi, then it counts as being pumped through the endpoint stalls sisi and titi, as well as through every stall along the path 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
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
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 50010
using namespace std;
int n,m,c=1,d=1;
int head[MAXN],deep[MAXN],son[MAXN],size[MAXN],fa[MAXN],id[MAXN],top[MAXN];
struct node1{
int next,to;
}a[MAXN<<1];
struct node2{
int data,c,l,r;
}b[MAXN<<2];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
namespace ST{
#define LSON rt<<1
#define RSON rt<<1|1
#define DATA(x) a[x].data
#define SIGN(x) a[x].c
#define LSIDE(x) a[x].l
#define RSIDE(x) a[x].r
#define WIDTH(x) (RSIDE(x)-LSIDE(x)+1)
struct Segment{
int data,c,l,r;
}a[MAXN<<2];
inline void pushup(int rt){
DATA(rt)=max(DATA(LSON),DATA(RSON));
}
inline void pushdown(int rt){
if(!SIGN(rt)||LSIDE(rt)==RSIDE(rt))return;
SIGN(LSON)+=SIGN(rt);DATA(LSON)+=SIGN(rt);
SIGN(RSON)+=SIGN(rt);DATA(RSON)+=SIGN(rt);
SIGN(rt)=0;
}
void buildtree(int l,int r,int rt){
int mid;
LSIDE(rt)=l;
RSIDE(rt)=r;
if(l==r){
DATA(rt)=0;
return;
}
mid=l+r>>1;
buildtree(l,mid,LSON);
buildtree(mid+1,r,RSON);
pushup(rt);
}
void update(int l,int r,int c,int rt){
int mid;
if(l<=LSIDE(rt)&&RSIDE(rt)<=r){
SIGN(rt)+=c;DATA(rt)+=c;
return;
}
pushdown(rt);
mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)update(l,r,c,LSON);
if(mid<r)update(l,r,c,RSON);
pushup(rt);
}
int query(int l,int r,int rt){
int mid,ans=0;
if(l<=LSIDE(rt)&&RSIDE(rt)<=r)return DATA(rt);
pushdown(rt);
mid=LSIDE(rt)+RSIDE(rt)>>1;
if(l<=mid)ans=max(ans,query(l,r,LSON));
if(mid<r)ans=max(ans,query(l,r,RSON));
return ans;
}
void work_add(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
update(id[top[x]],id[x],1,1);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
update(id[x],id[y],1,1);
return;
}
}
inline void add(int x,int y){
a[c].to=y;a[c].next=head[x];head[x]=c++;
a[c].to=x;a[c].next=head[y];head[y]=c++;
}
void dfs1(int rt){
son[rt]=0;size[rt]=1;
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(!deep[will]){
deep[will]=deep[rt]+1;
fa[will]=rt;
dfs1(will);
size[rt]+=size[will];
if(size[son[rt]]<size[will])son[rt]=will;
}
}
}
void dfs2(int rt,int f){
id[rt]=d++;top[rt]=f;
if(son[rt])dfs2(son[rt],f);
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(will!=fa[rt]&&will!=son[rt])
dfs2(will,will);
}
}
void work(){
int x,y;
while(m--){
x=read();y=read();
ST::work_add(x,y);
}
printf("%d\n",ST::query(1,n,1));
}
void init(){
int x,y;
n=read();m=read();
for(int i=1;i<n;i++){
x=read();y=read();
add(x,y);
}
deep[1]=1;
dfs1(1);
dfs2(1,1);
ST::buildtree(1,n,1);
}
int main(){
init();
work();
return 0;
}
总耗时3244ms。
解法二:
这题可以不用在线做,那么我们就有一个很NOIP的算法——树上差分!
若操作的节点是u,v,那么只要在差分数组num[]中这样:
int lca=LCA(u,v);
num[u]++;num[v]++;
num[lca]--;num[fa[lca]]--;
最后再用一个dfs求出和:
void get_sum(int rt){
sum[rt]=num[rt];
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(will==fa[rt])continue;
get_sum(will);
sum[rt]+=sum[will];
}
ans=max(ans,sum[rt]);
}
这样,sum[]数组中就是权值了。
那个LCA我不管你怎么求,反正什么倍增啊,树剖啊什么乱七八糟的玩意搞出来就行了。。。
附代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#define MAXN 50010
using namespace std;
int n,m,c=1,ans=0;
int num[MAXN],sum[MAXN],head[MAXN],deep[MAXN],son[MAXN],size[MAXN],fa[MAXN],top[MAXN];
struct node{
int next,to;
}a[MAXN<<1];
inline int read(){
int date=0,w=1;char c=0;
while(c<'0'||c>'9'){if(c=='-')w=-1;c=getchar();}
while(c>='0'&&c<='9'){date=date*10+c-'0';c=getchar();}
return date*w;
}
inline void add(int x,int y){
a[c].to=y;a[c].next=head[x];head[x]=c++;
a[c].to=x;a[c].next=head[y];head[y]=c++;
}
void dfs1(int rt){
son[rt]=0;size[rt]=1;
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(!deep[will]){
deep[will]=deep[rt]+1;
fa[will]=rt;
dfs1(will);
size[rt]+=size[will];
if(size[son[rt]]<size[will])son[rt]=will;
}
}
}
void dfs2(int rt,int f){
top[rt]=f;
if(son[rt])dfs2(son[rt],f);
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(will!=fa[rt]&&will!=son[rt])
dfs2(will,will);
}
}
int LCA(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]<deep[top[y]])swap(x,y);
x=fa[top[x]];
}
if(deep[x]>deep[y])swap(x,y);
return x;
}
void get_sum(int rt){
sum[rt]=num[rt];
for(int i=head[rt];i;i=a[i].next){
int will=a[i].to;
if(will==fa[rt])continue;
get_sum(will);
sum[rt]+=sum[will];
}
ans=max(ans,sum[rt]);
}
void work(){
int x,y;
while(m--){
x=read();y=read();
int lca=LCA(x,y);
num[x]++;num[y]++;num[lca]--;num[fa[lca]]--;
}
get_sum(1);
printf("%d\n",ans);
}
void init(){
int x,y;
n=read();m=read();
for(int i=1;i<n;i++){
x=read();y=read();
add(x,y);
}
deep[1]=1;
dfs1(1);
dfs2(1,1);
}
int main(){
init();
work();
return 0;
}
总耗时:780ms
由此,我们可以看到,树上差分的速度几乎是树剖的4倍!
在NOIP这种严重卡常的比赛中,不到万不得已,不要用两个log的算法。。。
BZOJ4390: [Usaco2015 dec]Max Flow的更多相关文章
- bzoj4390: [Usaco2015 dec]Max Flow(LCA+树上差分)
题目大意:给出一棵树,n(n<=5w)个节点,k(k<=10w)次修改,每次给定s和t,把s到t的路径上的点权+1,问k次操作后最大点权. 对于每次修改,给s和t的点权+1,给lca(s, ...
- BZOJ 4390: [Usaco2015 dec]Max Flow
4390: [Usaco2015 dec]Max Flow Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 177 Solved: 113[Submi ...
- [Usaco2015 dec]Max Flow 树上差分
[Usaco2015 dec]Max Flow Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 353 Solved: 236[Submit][Sta ...
- 【bzoj4390】[Usaco2015 dec]Max Flow LCA
题目描述 Farmer John has installed a new system of N−1 pipes to transport milk between the N stalls in h ...
- [Usaco2015 dec]Max Flow
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 204 Solved: 129[Submit][Status][Discuss] Descriptio ...
- 【BZOJ4391】[Usaco2015 dec]High Card Low Card(贪心)
[BZOJ4391][Usaco2015 dec]High Card Low Card(贪心) 题面 BZOJ 题解 预处理前缀后缀的结果,中间找个地方合并就好了. #include<iostr ...
- bzoj4393: [Usaco2015 Dec]Fruit Feast
题意: T,A,B.T是上限.A和B可以随意吃但是不能超过T.有一次将吃的东西/2的机会.然后可以继续吃,不能超过T.问最多可以吃多少. =>我们先处理不能/2可以吃到哪些.然后弄个双指针扫一扫 ...
- USACO Max Flow
洛谷 P3128 [USACO15DEC]最大流Max Flow 洛谷传送门 JDOJ 3027: USACO 2015 Dec Platinum 1.Max Flow JDOJ传送门 Descrip ...
- 洛谷P3128 [USACO15DEC]最大流Max Flow [树链剖分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
随机推荐
- group by与distinct效率分析及优化措施
如何使用group by进行去重 因为mysql的distinct在结果集中,全部不同,才可以去重.所以,当我们进行去重处理的时候,需要单独对某列进行去重,可以使用group by子句进行分组去重se ...
- 一款不错的编程字体Source Code Pro
我以前一直是用的MS自家的是Consolas的字体,这个字体基本上具有编程字体所需的所有要素:等宽.支持ClearType.中文字体大小合适,l和1,o和0很容易区分.非要挑刺的话就是字体比较小,9号 ...
- 使用Eclipse Memory Analyzer进行内存泄漏分析三部曲
源地址:http://seanhe.iteye.com/blog/898277 一.准备工作 分析较大的dump文件(根据我自己的经验2G以上的dump文件就需要使用以下介绍的方法,不然mat会出现 ...
- python super 的正确理解
http://www.jb51.net/article/87807.htm super指的是MRO中的下一个类
- PowerMockito的简单的介绍
转载:http://blog.csdn.net/u012881904/article/details/51334747 我们的依赖的配置 <properties> <powermoc ...
- MYSQL索引优化思维导图
有关索引的优化.MYSQL索引优化 文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing
- Webpack DLL
参考自:https://www.jianshu.com/p/a5b3c2284bb6 在用 Webpack 打包的时候,对于一些不经常更新的第三方库,比如 react,lodash,我们希望能和自己的 ...
- 转:十六进制颜色与RGB颜色对照表
http://www.vis.cc/html/ppyj/zscs/1090.html 十六进制颜色查询 颜 色 英文代码 形象描述 十六进制 RGB LightPink 浅粉红 #FFB6C1 255 ...
- OpenTSDB设计解读
OpenTSDB是基于HBase存储时间序列数据的一个开源数据库,确切地说,它仅仅是一个HBase的应用而已,其对于时间序列数据的处理能够供其它系统參考和借鉴.本文会针对它在数据库的设计方面展开一些探 ...
- mysql主从只同步部分库或表
同步部分数据有两个思路,1.master只发送需要的:2.slave只接收想要的. master端: binlog-do-db 二进制日志记录的数据库(多数据库用逗号,隔开)binlog-i ...