A:昔我往矣
lca+dfs序,先做出所有点的dfs序,然后对于每一个询问,以dfs序最小和最大的为两个端点,然后往里面加点相当于加上一条分叉出去的链,用LCA求解即可。
下附代码:
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 const ll INF=0X3f3f3f3f3f3f3f3f; 5 int Next[100005],to[100005]; 6 ll len[100005]; 7 int head[50005]; 8 ll tot=0; 9 int dep[50005],f[50005][20]; 10 ll l[50005][20],n,q; 11 int a[10]; 12 int dfn[50005],cnt; 13 struct node{ 14 ll p,l; 15 }; 16 bool cmp(int x,int y){ 17 return dfn[x]<dfn[y]; 18 } 19 inline void add(int a,int b,ll c){ 20 Next[tot]=head[a],to[tot]=b,len[tot]=c; 21 head[a]=tot++; 22 } 23 inline void deal(ll x,ll fa){ 24 dep[x]=dep[fa]+1; 25 for (int i=0; i<=16; i++){ 26 f[x][i+1]=f[f[x][i]][i]; 27 l[x][i+1]=l[x][i]+l[f[x][i]][i]; 28 } 29 for (int i=head[x]; i!=-1; i=Next[i]){ 30 int y=to[i]; 31 if (y==fa) continue; 32 f[y][0]=x; 33 l[y][0]=len[i]; 34 deal(y,x); 35 } 36 } 37 void dfs(int x,int pre){ 38 if (dfn[x]!=0) return; 39 dfn[x]=++cnt; 40 for (int i=head[x]; i!=-1; i=Next[i]){ 41 int y=to[i]; 42 if (y!=pre){ 43 dfs(y,x); 44 } 45 } 46 } 47 inline node lca(int x,int y){ 48 int tmp=x; 49 ll ret=0; 50 if (dep[x]<dep[y]) swap(x,y); 51 for (int i=16; i>=0; i--){ 52 if (dep[f[x][i]]>=dep[y]) { 53 ret+=l[x][i]; 54 x=f[x][i]; 55 } 56 if (x==y) { 57 return {y,ret}; 58 } 59 } 60 for (int i=16; i>=0; i--){ 61 if (f[x][i]!=f[y][i]){ 62 ret=ret+l[x][i]; 63 ret=ret+l[y][i]; 64 x=f[x][i]; 65 y=f[y][i]; 66 } 67 } 68 ret+=l[x][0]+l[y][0]; 69 return {f[x][0],ret}; 70 } 71 int main(){ 72 scanf("%lld",&n); 73 for (int i=0; i<n; i++){ 74 head[i]=-1; 75 } 76 for (int i=1; i<n; i++){ 77 ll a,b,c; 78 scanf("%lld%lld%lld",&a,&b,&c); 79 add(a,b,c); 80 add(b,a,c); 81 } 82 deal(0,-1); 83 scanf("%lld",&q); 84 cnt=0; 85 dfs(0,-1); 86 while (q--){ 87 for (int i=1; i<=5; i++){ 88 scanf("%lld",&a[i]); 89 } 90 sort(a+1,a+6,cmp); 91 node p=lca(a[1],a[5]); 92 ll res=p.l; 93 vector<int> now; 94 now.push_back(a[1]); 95 now.push_back(a[5]); 96 for (int i=2; i<=4; i++){ 97 int maxn=0,pp=0; 98 for (auto j:now){ 99 node p1=lca(a[i],j); 100 if (dep[p1.p]>maxn){ 101 maxn=dep[p1.p]; 102 pp=p1.p; 103 } 104 } 105 res+=lca(pp,a[i]).l; 106 now.push_back(a[i]); 107 } 108 printf("%lld\n",res); 109 } 110 return 0; 111 }View Code