题目连接:最大流Max Flow
题解:
这道题可以用树上点差分解决,也可以用树链剖分写,上一篇博客使用树上点差分写的,这次因为我刚学树剖,所以用树剖将这到题写了
树剖的写法:第一遍dfs()将重儿子,每个点的父亲,每个点的深度标记出来,第二遍dfs()按照重儿子的顺序进行有优先dfs()
得到当前的dfs序,此时树已经被剖分好了,然后我们就写一个线段树求区间最大值,因为是区间修改,所以需要用上懒人标记,如何修改树上任意一条链的权值,其实很简单,因为我们是按重儿子进行剖分的,所以重儿子上的dfs序一定是连续的,所以我们只需要将两个节点的头一致即可直接修改
注意:
我们先修改深度大的,这样就不会产生多修改的情况了,每次比较当前节点所在链的头的深度,修改深度大的节点和它的头所在的链即可
while(top[x]!=top[y)
{
if(deep[top[x]]<deep[top[y]])
{
}
}
AC代码:
#include<bits/stdc++.h>
using namespace std;
//p3128 树链剖分
const int maxn=1e5+5;
int n,q,cnt1,cnt2;
int head[maxn],sizx[maxn],pre[maxn],deep[maxn],son[maxn];
int dfn[maxn],topx[maxn];
struct node
{
int to,nex;
} edge[maxn*2];
void add(int u,int v)
{
edge[cnt1].to=v;
edge[cnt1].nex=head[u];
head[u]=cnt1++;
}
void dfs1(int u,int fa)
{
deep[u]=deep[fa]+1;
pre[u]=fa;
sizx[u]=1;
int maxson=-1;
for(int i=head[u]; ~i; i=edge[i].nex)
{
int v=edge[i].to;
if(v!=fa)
{
dfs1(v,u);
sizx[u]+=sizx[v];
if(sizx[v]>maxson)
{
maxson=sizx[v];
son[u]=v;
}
}
}
}
void dfs2(int u,int top)
{
dfn[u]=++cnt2;
topx[u]=top;
if(!son[u])
{
return ;
}
dfs2(son[u],top);
for(int i=head[u]; ~i; i=edge[i].nex)
{
int v=edge[i].to;
if(v==son[u]||v==pre[u])
continue;
dfs2(v,v);
}
}
struct yzj
{
int l,r,maxx,lazy;
} tr[maxn*4];
void pushup(int k)
{
tr[k].maxx=max(tr[k<<1].maxx,tr[k<<1|1].maxx);
}
void pushdown(int k)
{
tr[k<<1].lazy+=tr[k].lazy;
tr[k<<1|1].lazy+=tr[k].lazy;
tr[k<<1].maxx+=tr[k].lazy;
tr[k<<1|1].maxx+=tr[k].lazy;
tr[k].lazy=0;
}
void build(int k,int l,int r)
{
tr[k].l=l,tr[k].r=r,tr[k].lazy=0;
if(l==r)
{
tr[k].maxx=0;
return ;
}
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
pushup(k);
}
void modify(int k,int l,int r,int w)
{
if(tr[k].l>=l&&tr[k].r<=r)
{
tr[k].maxx+=w;
tr[k].lazy+=w;
return;
}
pushdown(k);
int mid=tr[k].l+tr[k].r>>1;
if(mid>=r)
{
modify(k<<1,l,r,w);
}
else if(mid<l)
{
modify(k<<1|1,l,r,w);
}
else
{
modify(k<<1,l,mid,w);
modify(k<<1|1,mid+1,r,w);
}
pushup(k);
}
int qmaxson(int k,int l,int r)
{
if(tr[k].l>=l&&tr[k].r<=r)
{
return tr[k].maxx;
}
pushdown(k);
int mid=tr[k].l+tr[k].r>>1;
if(mid>=r)
{
return qmaxson(k<<1,l,r);
}
else if(mid<l)
{
return qmaxson(k<<1|1,l,r);
}
else
{
return max(qmaxson(k<<1,l,mid),qmaxson(k<<1|1,mid+1,r));
}
}
void modify_son(int x,int y,int w)
{
//cout<<"8***"<<endl;
while(topx[x]!=topx[y])
{
//printf("**\n");
if(deep[topx[x]]<deep[topx[y]])
swap(x,y);
modify(1,dfn[topx[x]],dfn[x],w);
x=pre[topx[x]];
}
if(deep[x]>deep[y])
swap(x,y);
//cout<<"8***"<<endl;
modify(1,dfn[x],dfn[y],w);
}
int main()
{
memset(head,-1,sizeof(head));
scanf("%d %d",&n,&q);
int u,v;
for(int i=1; i<n; i++)
{
scanf("%d %d",&u,&v);
add(u,v);
add(v,u);
}
dfs1(1,0);
dfs2(1,1);
build(1,1,n);
while(q--)
{
scanf("%d %d",&u,&v);
modify_son(u,v,1);
}
printf("%d\n",qmaxson(1,1,n));
}