【USACO15DEC】最大流Max Flow(树链剖分)

题目见洛谷。

分析

题意:给你一棵N个节点,N-1条边的树,每个点权值为0。然后有一些操作,给某两个点之间所有点权值加上1,最后输出最大的权值。

这就是裸的树链剖分了,甚至连查询都只用一次...

#include<bits/stdc++.h>
using namespace std;
const int MAXN=50005;
int val[MAXN*2],lc[MAXN*2],rc[MAXN*2],add[MAXN*2];
int dfs_pos[MAXN],b[MAXN],a[MAXN],top_node[MAXN],dep[MAXN],size[MAXN],big_son[MAXN],last[MAXN],fa[MAXN];
int N,K,np2=0,dfs_clock=0,np=0,rt=0;
struct edge{int to,pre;}E[MAXN*2];

char c;
void scan(int &x)
{
	for(c=getchar();c<'0'||c>'9';c=getchar());
	for(x=0;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
}

void addedge(int u,int v)
{
	E[++np2]=(edge){v,last[u]};
	last[u]=np2;
}

void DFS1(int i,int f,int d)
{
	dep[i]=d; fa[i]=f; size[i]=1;
	for(int p=last[i];p;p=E[p].pre)
	{
		int j=E[p].to;
		if(j==f) continue;
		DFS1(j,i,d+1); size[i]+=size[j];
		if(size[j]>size[big_son[i]]) big_son[i]=j;
	}
}

void DFS2(int i,int top)
{
	dfs_pos[i]=++dfs_clock;
	b[dfs_clock]=a[i]; top_node[i]=top;
	if(!big_son[i]) return;
	DFS2(big_son[i],top);
	for(int p=last[i];p;p=E[p].pre)
	{
		int j=E[p].to;
		if(j==fa[i]||j==big_son[i]) continue;
		DFS2(j,j);
	}
}

void build(int &now,int L,int R)
{
	if(!now) now=++np;
	if(L==R)
	{
		val[now]=b[L];
		return;
	}
	int mid=(L+R)/2;
	build(lc[now],L,mid);
	build(rc[now],mid+1,R);
}

void pushdown(int now)
{
	if(!add[now]) return;
	val[lc[now]]+=add[now];val[rc[now]]+=add[now];
	add[lc[now]]+=add[now];add[rc[now]]+=add[now];
	add[now]=0;
}

void update(int now,int L,int R,int i,int j)
{
	if(i<=L&&R<=j)
	{
		add[now]+=1;
		val[now]+=1;
		return;
	}
	pushdown(now); int mid=(L+R)/2;
	if(i<=mid) update(lc[now],L,mid,i,j);
	if(mid<j) update(rc[now],mid+1,R,i,j);
}

void uprange(int u,int v)
{
	while(top_node[u]!=top_node[v])
	{
		if(dep[top_node[u]]<dep[top_node[v]]) swap(u,v);
		update(rt,1,N,dfs_pos[top_node[u]],dfs_pos[u]);
		u=fa[top_node[u]];
	}
	if(dep[u]>dep[v]) swap(u,v);
	update(rt,1,N,dfs_pos[u],dfs_pos[v]);
}

int ques(int now,int L,int R)
{
	if(L==R) return val[now];
	pushdown(now); int mid=(L+R)/2;
	return max(ques(lc[now],L,mid),ques(rc[now],mid+1,R));
}

int main()
{
	scan(N);scan(K);
	int i,u,v;
	for(i=1;i<N;i++)
	{
		scan(u);scan(v);
		addedge(u,v);
		addedge(v,u);
	}
	DFS1(1,0,1); DFS2(1,1); build(rt,1,N);
	while(K--)
	{
		scan(u);scan(v);
		uprange(u,v);
	}
	cout<<ques(rt,1,N);
}

猜你喜欢

转载自blog.csdn.net/WWWengine/article/details/81630319