[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;
}

 

posted @ 2018-04-20 15:15  qjs12  阅读(103)  评论(0编辑  收藏  举报