https://www.dotcpp.com/oj/problem3156.html
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define INF 0x3f3f3f3f3f3f3f3f
const int N =1e5+5;
int dep[N],f[N][50],dis[N],luxian[N];
struct edge{
int u;
int v;
int d;
};
vector<edge>e[N];
int n,k;
void dfs(int u,int fa,int d)
{
dep[u]=dep[fa]+1; // 记录深度
dis[u]=d;
f[u][0]=fa; //ST表
//初始化ST表
for (int i=1;(1<<i) <= dep[u];++i)
{
f[u][i]=f[f[u][i-1]][i-1];
}
for (int i=0;i<e[u].size();++i )
{
edge v=e[u][i];
if (v.v == fa) continue;
dfs(v.v,u,v.d+dis[u]);
}
}
int lca(int x,int y)
{
//保证x在y的下面
if (dep[x]< dep[y]) swap(x,y);
//向上跳,直到x的深度和y相同,然后再一起找共同祖先,如果x==y了,那么共同祖先就是x
for (int i=__lg(n);i>=0;--i)
{
if (dep[f[x][i]] >= dep[y]) x=f[x][i];
if (x==y) return x;
}
//到了同一深度之后,就开始一起向上跳
for (int i=__lg(n);i>=0;--i)
{
if (f[x][i]!=f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
int get(int x ,int y)
{
return dis[x]+dis[y]-dis[lca(x,y)]*2;
}
signed main()
{
cin>>n>>k;
for (int i=0;i<n-1; ++i)
{
int u,v,d;
cin>>u>>v>>d;
e[u].push_back({u,v,d});
e[v].push_back({v,u,d});
}
for (int i=1;i<=k;++i)
{
cin>>luxian[i];
}
dfs(1,0,0);
int sum=0;
for (int i=1;i<k;++i)
{
sum+=get(luxian[i],luxian[i+1]);
}
for (int i=1;i<=k;++i)
{
int ans=sum;
//减掉路径的消耗
if (i!=1) ans-=get(luxian[i],luxian[i-1]);
if (i!=k) ans-=get(luxian[i],luxian[i+1]);
if (i!=1 && i!=k) ans+=get(luxian[i-1],luxian[i+1]);
cout<<ans<<" ";
}
}
https://www.dotcpp.com/oj/problem3157.html
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define INF 0x3f3f3f3f3f3f3f3f
const int N =1e5+5;
int dep[N],f[N][25],id[N],n,m,s[N];
struct edge{
int id;
int to;
};
vector<edge>e[N];
void dfs(int u,int fa)
{
dep[u]=dep[fa]+1;
f[u][0]=fa;
for (int i=1;(1<<i) <= dep[u];++i)
{
f[u][i]=f[f[u][i-1]][i-1];
}
for (int i=0;i<e[u].size();++i)
{
edge v=e[u][i];
if (v.to == fa) continue;
dfs(v.to,u);
id[v.to]=v.id;
}
}
int lca(int x,int y)
{
if (dep[x] < dep[y]) swap(x,y);
while (dep[x] > dep[y])
{
x=f[x][__lg(dep[x] -dep[y] -1)];
}
if (x==y) return x;
for (int i=1 ; i<=20 ; ++i)
{
if (f[x][i] != f[y][i])
{
x=f[x][i];
y=f[y][i];
}
}
return f[x][0];
}
//和LCA相比增加的部分---差分
void add(int l,int r)
{
s[l]++;
s[r]++;
s[lca(l,r)]-=2;
}
//计算子树和
void cal_sum(int u,int fa)
{
for (int i=0;i<e[u].size();++i)
{
edge v=e[u][i];
if (v.to==fa) continue;
cal_sum(v.to,u);
s[u]+=s[v.to];
}
}
signed main()
{
cin>>n>>m;
for (int i=1;i<n;++i)
{
int u,v;
cin>>u>>v;
e[u].push_back({i,v});
e[v].push_back({i,u});
}
dfs(1,0);
for (int i=0;i<m;++i)
{
int l;
int r;
cin>>l>>r;
add(l,r);
}
cal_sum(1,0);
int ans=0;
for (int i=1;i<=n;++i)
{
if (s[i] == m && ans < id[i]) ans=id[i];
}
cout<<ans;
}