[USACO15DEC] Max Flow P- tree difference + LCA

topic

Topic
subject to the effect:

FJ to his barn N installed between N-1 of conduits (2≤N≤50,000) compartments, the compartments are numbered from 1 to N. All the compartments are in communication pipe.
There FJ K (1≤K≤100,000) milk transport route, a route leading from the i-th compartment to compartment si ti. Pressure a transport route will give its compartment and all the compartments of the middle route of two endpoints to bring pressure on the transportation of a unit, you need to calculate the maximum pressure compartment is.

answer

This question does not need to be modified online, so no tree cross-section (I will not cross the tree), a tree difference can be used directly.
Opening a differential array a, such as applying pressure between the points u and v then performed

int t=lca(u,v);
a[u]++;
a[v]++;
a[t]--;
a[f[t][0]]--;  //f[t][0]意为t的父节点

Before the final output, performs a tree dfs, the difference array seek prefix and the next, the maximum value of statistics on the line.

#include <cstdio>
#include <queue>
#include <cmath>
using namespace std;
const int N=1E6;
int a[N],maxn;
int head[N],nxt[N],to[N],cnt;
int n,m,s,d[N],dep;
int f[N][21];
bool v[N];
queue<int> q;

void add(int x,int y) { //还是使用链式前向星
	to[++cnt]=y;
	nxt[cnt]=head[x];
	head[x]=cnt;
}

int lca(int x,int y) {
	if(d[x]>d[y]) swap(x,y);
	for(int i=dep;i>=0;i--)
	  if(d[f[y][i]]>=d[x]) y=f[y][i];
	if(x==y) return x;
	for(int i=dep;i>=0;i--)
	  if(f[x][i]!=f[y][i])
	    x=f[x][i],y=f[y][i];
	return f[x][0];
}

void bfs() {
	q.push(s);
	d[s]=1;
	while(!q.empty()) {
		int t=q.front();
		q.pop();
		for(int i=head[t];i;i=nxt[i]) {
			int y=to[i];
			if(d[y]) continue;
			d[y]=d[t]+1;
			f[y][0]=t;
			for(int j=1;j<=dep;j++)
			  f[y][j]=f[f[y][j-1]][j-1];
			q.push(y);
		}
	}
}

void dfs(int x) {
	v[x]=true;
	for(int i=head[x];i;i=nxt[i]) {
		int y=to[i];
		if(v[y])
		  continue;
		dfs(y);
		a[x]+=a[y];
	}
	maxn=max(maxn,a[x]);
}

int main() {
	scanf("%d%d",&n,&m);
	s=1;    //根结点随便取
	dep=log2(n)+1;
	for(int i=1;i<=n-1;i++) {
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
		add(y,x);
	}
	bfs();
	while(m--) {
		int x,y;
		scanf("%d%d",&x,&y);
		int t=lca(x,y); //萌新,不会lca的离线tarjan算法
		a[t]--;
		a[f[t][0]]--;
		a[x]++;
		a[y]++;
	}
	dfs(s);
	printf("%d",maxn);
	return 0;
}

Error-prone point

Finally, record the reasons I had wrong.
It is to

void dfs(int x) {
	v[x]=true;
	for(int i=head[x];i;i=nxt[i]) {
		int y=to[i];
		if(v[y])
		  continue;
		dfs(y);
		a[x]+=a[y];
	}
	maxn=max(maxn,a[x]);
}

Wrote

void dfs(int x) {
	for(int i=head[x];i;i=nxt[i]) {
		int y=to[i];
		if(v[y])
		  continue;
                v[y]=true;  //这儿不同哦
		dfs(y);
		a[x]+=a[y];
	}
	maxn=max(maxn,a[x]);
}

This way, then the root may count twice, the last of the maximum value will be different.

Guess you like

Origin www.cnblogs.com/wyc06/p/12664372.html