[USACO Oct08] 牧场旅行
倍增,Tarjan,树剖。
我选择树剖。
// q.c
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int M=1000+10;
/***********************************************************************/
struct Edge {
int u,v,nex,val; Edge() {}
Edge(int a,int b,int c,int d):u(a),v(b),nex(c),val(d) {}
}ed[M<<1];
int head[M],cnt;
void add_edge(int a,int b,int c) {
ed[cnt]=Edge(a,b,head[a],c); head[a]=cnt++;
ed[cnt]=Edge(b,a,head[b],c); head[b]=cnt++;
}
/***********************************************************************/
int dep[M],size[M],son[M],f[M],dis[M];
void dfs1(int u,int fa,int d,int ds) {
f[u]=fa; dep[u]=d; size[u]=1; dis[u]=ds;
int i; Edge e;
for(i=head[u];~i;i=ed[i].nex) {
e=ed[i];
if(!f[e.v]) {
dfs1(e.v,u,d+1,ds+e.val); size[u]+=size[e.v];
if(size[e.v]>size[son[u]]||!son[u]) son[u]=e.v;
}
}
}
int top[M];
void dfs2(int u,int TP) {
top[u]=TP; if(!son[u]) return ;
dfs2(son[u],TP);
int i; Edge e;
for(i=head[u];~i;i=ed[i].nex) {
e=ed[i];
if(e.v!=f[u]&&e.v!=son[u]) dfs2(e.v,e.v);
}
}
int lca(int a,int b) {
while(top[a]!=top[b]) {
if(dep[top[a]]<dep[top[b]]) swap(a,b);
a=f[top[a]];
}
return dep[a]<dep[b]?a:b;
}
/***********************************************************************/
int main() {
freopen("pwalk.in","r",stdin);
freopen("pwalk.out","w",stdout);
int n,q,a,b,c;
scanf("%d%d",&n,&q);
memset(head,-1,sizeof(head));
for(int i=1;i<n;i++) {
scanf("%d%d%d",&a,&b,&c);
add_edge(a,b,c);
}
dfs1(1,-1,0,0); dfs2(1,1);
for(int i=1;i<=q;i++) {
scanf("%d%d",&a,&b);
c=lca(a,b);
printf("%d\n",dis[a]+dis[b]-(dis[c]<<1));
}
return 0;
}

浙公网安备 33010602011771号