题解
从一个点运输牛奶到另一个点,求最大压力的点是那个点?
很显然,运输牛奶是从一个点运输到这两个点的LCA之后再运到另一个点
最后是修改很显然一个点一个点去加一是TLE的所以,我们要用一个差分的思想:
用record[]数组,两个点各加一,LCA减一,LCA的父亲减一
最后用dfs搜索一遍就出答案了
代码
tarjan法求LCA,tmpfa存tarjan用的fa
fa只存这一点的上一级
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int n,q,ans;
int toq[600100],nxtq[600100],headq[300100],totq;
int top[600100],nxtp[600100],headp[300100],totp;
int tmpfa[300100],fa[300100],record[300100];
bool vis[300100];
void addq(int f,int t)
{
toq[++totq] = t;
nxtq[totq] = headq[f];
headq[f] = totq;
}
void addp(int f,int t)
{
top[++totp] = t;
nxtp[totp] = headp[f];
headp[f] = totp;
}
int find(int x){
if(tmpfa[x] == x)return x;
return tmpfa[x] = find(tmpfa[x]);
}
void tarjan(int pos,int pre)
{
tmpfa[pos] = pos;
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre){
tarjan(top[i],pos);
tmpfa[top[i]] = pos;
}
vis[pos] = true;
for(int i = headq[pos];i;i = nxtq[i])
if(vis[toq[i]]){
int tmp_lca = find(toq[i]);
record[tmp_lca]--,record[fa[tmp_lca]]--,record[pos]++,record[toq[i]]++;
}
}
void dfs(int pos,int pre)
{
fa[pos] = pre;
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre)
dfs(top[i],pos);
}
void dfsans(int pos,int pre)
{
for(int i = headp[pos];i;i = nxtp[i])
if(top[i] != pre){
dfsans(top[i],pos);
record[pos] += record[top[i]];
}
ans = max(record[pos],ans);
}
int main()
{
scanf("%d%d",&n,&q);
int f,t,ori;
for(int i = 1;i < n;i++){
scanf("%d%d",&f,&t);
addp(f,t),addp(t,f);
}
for(int i = 1;i <= q;i++){
scanf("%d%d",&f,&t);
addq(f,t),addq(t,f);
}
dfs(1,0);
tarjan(1,0);
dfsans(1,0);
printf("%d\n",ans);
}