\[ dep[u]+w[u]=dep[s]——往左走\dep[u]-w[u]=dep[s]——往右走 \]
\[ w[u]=dep[u]{\Rightarrow}dep[u]-w[u]=0=dep[s] \]
\[ dep[u]+w[u]=dep[s] \]
\[ dep[u]+w[u]=dep[s[sd[u]]]\dep[u]-w[u]=dep[t[td[u]]]-dist(s[td[u]],t[td[u]])-pretime(td[u]) \]
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define maxn 300001
#define maxm 300001
using namespace std;
struct graph{
struct edge{
int to,next; bool flag;
edge(){}
edge(const int &_to,const int &_next,const bool &_flag){ to=_to,next=_next,flag=_flag; }
}e[maxn<<1];
int head[maxn],k;
inline void init(){ memset(head,-1,sizeof head); }
inline void add(const int &u,const int &v,const bool &f){ e[k]=edge(v,head[u],f),head[u]=k++; }
}g,q;//g为题目给的树,q为询问
vector<int> su[maxn],sd[maxn],tu[maxn],td[maxn];
int s[maxm<<1],t[maxm<<1],tot;
int pretime[maxm<<1],dis[maxm<<1],cnts[maxn<<1],cntt[maxn<<1],Lca[maxm<<1];
int fa[maxn],dep[maxn];
bool vis[maxn];
int n,m,w[maxn],ans[maxn];
inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(c=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
/*----------------tarjan---------------*/
int get(int x){ return x==fa[x]?x:fa[x]=get(fa[x]); }
void lca_tarjan(int u,int pre){
fa[u]=u,dep[u]=dep[pre]+1,vis[u]=true;
for(register int i=g.head[u];~i;i=g.e[i].next){
int v=g.e[i].to;
if(v!=pre) lca_tarjan(v,u),fa[v]=u;
}
for(register int i=q.head[u];~i;i=q.e[i].next){
int v=q.e[i].to; bool rev=false;
if(!vis[v]||q.e[i].flag) continue;
q.e[i].flag=q.e[i^1].flag=true;
int lca=get(v);
if(i&1) rev=true,swap(u,v);
if(u==lca){
s[++tot]=u,t[tot]=v;
su[u].push_back(tot),td[v].push_back(tot);
dis[tot]=dep[v]-dep[u];
}else if(v==lca){
s[++tot]=u,t[tot]=v;
sd[u].push_back(tot),tu[v].push_back(tot);
dis[tot]=dep[u]-dep[v];
}else{
s[++tot]=lca,t[tot]=v;
su[lca].push_back(tot),td[v].push_back(tot);
dis[tot]=dep[v]-dep[lca];
pretime[tot]=dep[u]-dep[lca];
Lca[++tot]=lca;
s[tot]=u,t[tot]=lca;
sd[u].push_back(tot),tu[lca].push_back(tot);
dis[tot]=dep[u]-dep[lca];
}
if(rev) u=v;
}
}
/*---------------getans---------------*/
void dfs(int u,int pre){
int nows=cnts[dep[u]+w[u]+maxn],nowt=cntt[dep[u]-w[u]+maxn];
for(register int i=0;i<sd[u].size();i++) cnts[dep[s[sd[u][i]]]+maxn]++;
for(register int i=0;i<td[u].size();i++) cntt[dep[t[td[u][i]]]-dis[td[u][i]]-pretime[td[u][i]]+maxn]++;
for(register int i=g.head[u];~i;i=g.e[i].next){
int v=g.e[i].to;
if(v!=pre) dfs(v,u);
}
ans[u]=cnts[dep[u]+w[u]+maxn]-nows+cntt[dep[u]-w[u]+maxn]-nowt;
for(register int i=0;i<tu[u].size();i++) if(Lca[tu[u][i]]==u&&dep[s[tu[u][i]]]+maxn==dep[u]+w[u]+maxn) ans[u]--;
for(register int i=0;i<tu[u].size();i++) cnts[dep[s[tu[u][i]]]+maxn]--;
for(register int i=0;i<su[u].size();i++) cntt[dep[t[su[u][i]]]-dis[su[u][i]]-pretime[su[u][i]]+maxn]--;
}
int main(){
/*------------init---------------*/
g.init(),q.init();
n=read(),m=read();
for(register int i=1;i<n;i++){
int u=read(),v=read();
g.add(u,v,false),g.add(v,u,false);
}
for(register int i=1;i<=n;i++) w[i]=read();
for(register int i=1;i<=m;i++){
int u=read(),v=read();
q.add(u,v,false),q.add(v,u,false);
}
/*-------------------------------*/
lca_tarjan(1,0);
dfs(1,0);
for(register int i=1;i<=n;i++) printf("%d ",ans[i]);puts("");
return 0;
}
原文:https://www.cnblogs.com/akura/p/10933441.html