Skip to content

tarjan离线求LCA ​

cpp
int par[N];
vector<int> adj[N];
vector<PII> query[N];
bool vis[N];
int ans[N];
int find(int x){
    return par[x]==x?x:par[x]=find(par[x]);
}
void tarjan(int u,int fa){
    vis[u]=true;
    for(auto v:adj[u]){
        if(v==fa)continue;
        tarjan(v,u);
        par[v]=u;
    }
    for(auto [id,v]:query[u]){
        if(vis[v])ans[id]=find(v);
    }
}

三个点到一个点的最小花费最小 ​

  • 三个点的lca必有两个相同
  • 两个相同,那么就是另一个点
  • 三个相同,就是当前点

树上差分 ​

cpp
//点差分
w[u]+=x,w[v]+=x,w[lca(u,v)]-=x,w[fa[lca(u,v)]]-=x;
//边差分
w[u]+=x,w[v]+=x,w[lca(u,v)]-=2*x;