【题解】[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;
}

浙公网安备 33010602011771号