比赛 ZLXOI2015Day2 评测结果 AAAAAAAAAA
题目名称 ZLX的陨落 最终得分 100
用户昵称 forever 运行时间 0.985 s
代码语言 C++ 内存使用 28.52 MiB
提交时间 2015-10-30 19:16:33
显示代码纯文本
/*==========Author:hzoi-GCJ===============*/
/*==========Algorithm:倍增+lca===========*/
#include<cstdio>
#include<vector>
using namespace std;
#define LL long long
struct dd{
	int begin,end,juli,next;
}jie[300005];
int f[100002][30],fa[100002][30],deep[100002],head[100002];
long long Ans;
int tot;
void add(int x,int y,int z){
	jie[++tot].begin=x; jie[tot].end=y; jie[tot].juli=z; jie[tot].next=head[x]; head[x]=tot;
}
int n,m,q;
void dfs(int x){
	for(int i=head[x];i;i=jie[i].next){
		if(!deep[jie[i].end]){
			deep[jie[i].end]=deep[x]+1;
			f[jie[i].end][0]=jie[i].juli;
			fa[jie[i].end][0]=x;
			dfs(jie[i].end);
		}
	}
}
inline void Swap(int &x,int &y){
	x^=y; y^=x; x^=y;
}
inline LL LCA(int x,int y){
	if(deep[x]<deep[y]) Swap(x,y);
	int i;
	for(i=0;(1<<i)<=deep[x];i++);
	i--;
	for(int j=i;j>=0;--j){
		if(deep[x]-(1<<j)>=deep[y]){
			Ans+=(LL)f[x][j];
			x=fa[x][j];
		}
	}
	if(x==y) return Ans;
	for(int j=i;j>=0;--j){
		if(fa[x][j]!=fa[y][j]){
			Ans+=(LL)f[x][j]+f[y][j];
			x=fa[x][j]; y=fa[y][j];
		}
	}
	Ans+=f[x][0]+f[y][0];
	return Ans;
}
int main(){
	freopen("ThefallingofZLX.in","r",stdin);
    freopen("ThefallingofZLX.out","w",stdout);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;++i){
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		add(x,y,z);add(y,x,z);
	}
	deep[1]=1;
	dfs(1);
	for(int j=1;(1<<j)<=n;++j)
	 for(int i=1;i<=n;++i){
		fa[i][j]=fa[fa[i][j-1]][j-1];
		f[i][j]=f[i][j-1]+f[fa[i][j-1]][j-1];
	 }
	scanf("%d",&q);
	for(int i=1;i<=q;++i){
		int x,y;
		scanf("%d%d",&x,&y);
		Ans=0;
		printf("%lld\n",LCA(x,y));
	}
	return 0;
}