【题解】[USACO15DEC]最大流Max Flow

[USACO15DEC]最大流Max Flow

题意

传送门

解法

就是统计树上每个点被多少条非树边所覆盖,树上差分一下就好了。
注意这是点差分而不是边差分,所以lca要归于一条边上,所以要:
$ --co[lca],--co[fa[lca]] $

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <cctype>
#include <vector>
#include <queue>
#define INF 2139062143
#define MAX 0x7ffffffffffffff
#define del(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
template<typename T>
inline void read(T&x)
{
    x=0;T k=1;char c=getchar();
    while(!isdigit(c)){if(c=='-')k=-1;c=getchar();}
    while(isdigit(c)){x=x*10+c-'0';c=getchar();}x*=k;
}
const int maxn=5e4+15;
vector<int> G[maxn];
void add_edge(int u,int v) {
	G[u].push_back(v);
	G[v].push_back(u);
}

int fa[maxn],sz[maxn],son[maxn],top[maxn],dep[maxn];

void dfs1(int u,int f) {
	dep[u]=dep[f]+1;fa[u]=f;son[u]=0;sz[u]=1;
	for(int i=0;i<G[u].size();i++) {
		int v=G[u][i];
		if(v==f) continue;
		dfs1(v,u);
		sz[u]+=sz[v];
		if(sz[v]>sz[son[u]]) son[u]=v;
	}
}

void dfs2(int u,int topf) {
	top[u]=topf;
	if(son[u]) dfs2(son[u],topf);
	for(int i=0;i<G[u].size();i++) {
		int v=G[u][i];
		if(v==fa[u]||v==son[u]) continue;
		dfs2(v,v);
	}
}

int LCA(int x,int y) {
	while(top[x]!=top[y]) {
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		x=fa[top[x]];
	}
	if(dep[x]>dep[y]) swap(x,y);
	return x;
}

int co[maxn];

void dfs(int u) {
	for(int i=0;i<G[u].size();i++) {
		int v=G[u][i];
		if(v==fa[u]) continue;
		dfs(v);
		co[u]+=co[v];
	}
}

int n,k;
int main()
{
	read(n),read(k);
	int u,v;
	for(int i=1;i<n;i++) {
		read(u),read(v);
		add_edge(u,v);
	}
	dfs1(1,0);dfs2(1,1);
	for(int i=1;i<=k;i++) {
		read(u),read(v);
		int lca=LCA(u,v);
		++co[u];++co[v];
		--co[lca];--co[fa[lca]];
	}
	dfs(1);
	int ans=0;
	for(int i=1;i<=n;i++) ans=max(ans,co[i]);
	printf("%d\n",ans);
	return 0;
}
posted @ 2018-10-04 18:32  Mr_asd  阅读(163)  评论(0)    收藏  举报