列表

详情


NC50470. Dis

描述

给出n个点的一棵树,多次询问两点之间的最短距离。
注意:边是双向的。

输入描述

第一行为两个整数n和m。n表示点数,m表示询问次数;
下来n-1行,每行三个整数x,y,k,表示点x和点y之间存在一条边长度为k;
再接下来m行,每行两个整数x,y,表示询问点x到点y的最短距离。

输出描述

输出m行。对于每次询问,输出一行。

示例1

输入:

2 2 
1 2 100 
1 2 
2 1

输出:

100
100

示例2

输入:

3 2
1 2 10
3 1 15
1 2
3 2

输出:

10
25

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 86ms, 内存消耗: 2064K, 提交时间: 2020-01-21 11:34:41

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e4+1;

int F[MAXN][20];
int D[MAXN];
int H[MAXN];
vector<pair<int, int>> G[MAXN];
int N, M;

void dfs(int s, int f, int d) {
  F[s][0] = f, H[s]=H[f]+1, D[s] = d;
  for (int i = 0; i < 19; i++) F[s][i+1] = F[F[s][i]][i];
  for (auto it: G[s]) {
    int t = it.first, w = it.second;
    if (t != f) dfs(t, s, w + d);
  }
}

int lca(int x, int y) {
  if (H[x] < H[y]) swap(x, y);
  for (int i = 19; i >= 0; i--) if (H[F[x][i]] >= H[y]) x = F[x][i];
  if (x == y) return x;
  for (int i = 19; i >= 0; i--) if (F[x][i] != F[y][i]) x = F[x][i], y = F[y][i];
  return F[x][0];
}

int main() {
  cin >> N >> M;
  for (int i = 0; i < N - 1; i++) {
    int x, y, k; cin >> x >> y >> k;
    G[x].push_back({y, k});
    G[y].push_back({x, k});
  }
  dfs(1, 0, 0);
  while (M--) {
    int x, y; cin >> x >> y;
    int z = lca(x, y);
    cout << D[x] + D[y] - 2 * D[z] << endl;
  }
}

C++11(clang++ 3.9) 解法, 执行用时: 113ms, 内存消耗: 2392K, 提交时间: 2020-05-30 20:50:02

#include<bits/stdc++.h>
using namespace std;
const int MAXN=1e4+1;
int F[MAXN][20];
int D[MAXN];
int H[MAXN];
vector<pair<int,int> >G[MAXN];
int N,M;
void dfs(int s,int f,int d)
{
	F[s][0]=f,H[s]=H[f]+1,D[s]=d;
	for(int i=0;i<19;i++)
	F[s][i+1]=F[F[s][i]][i];
	for(auto it:G[s])
	{
		int t=it.first,w=it.second;
		if(t!=f)
		dfs(t,s,w+d);
	}
}
int lca(int x,int y)
{
	if(H[x]<H[y]) swap(x,y);
	for(int i=19;i>=0;i--)
	if(H[F[x][i]]>=H[y])
	x=F[x][i];
	if(x==y)
	return x;
	for(int i=19;i>=0;i--)
	if(F[x][i]!=F[y][i])
	x=F[x][i],y=F[y][i];
	return F[x][0];
}
int main()
{
	cin>>N>>M;
	for(int i=0;i<N-1;i++)
	{
		int x,y,k;
		cin>>x>>y>>k;
		G[x].push_back({y,k});
		G[y].push_back({x,k});
	}
	dfs(1,0,0);
	while(M--)
	{
		int x,y;
		cin>>x>>y;
		int z=lca(x,y);
		cout<<D[x]+D[y]-2*D[z]<<endl;
	}
}

上一题