题目描述
You are given a tree with N vertices.
Here, a tree is a kind of graph, and more specifically, a connected undirected graph with N−1 edges, where N is the number of its vertices.
The i-th edge (1≤i≤N−1) connects Vertices ai and bi, and has a length of ci.
You are also given Q queries and an integer K. In the j-th query (1≤j≤Q):
find the length of the shortest path from Vertex xj and Vertex yj via Vertex K.
Constraints
3≤N≤105
1≤ai,bi≤N(1≤i≤N−1)
1≤ci≤109(1≤i≤N−1)
The given graph is a tree.
1≤Q≤105
1≤K≤N
1≤xj,yj≤N(1≤j≤Q)
xj≠yj(1≤j≤Q)
xj≠K,yj≠K(1≤j≤Q)
- 输入
- Input is given from Standard Input in the following format:
- N
- a1 b1 c1
- aN−1 bN−1 cN−1
Q K
x1 y1 - xQ yQ
输出
Print the responses to the queries in Q lines.
In the j-th line j(1≤j≤Q), print the response to the j-th query.
样例输入
5
1 2 1
1 3 1
2 4 1
3 5 1
3 1
2 4
2 3
4 5
样例输出
3
2
4
提示
The shortest paths for the three queries are as follows:
Query 1: Vertex 2 → Vertex 1 → Vertex 2 → Vertex 4 : Length 1+1+1=3
Query 2: Vertex 2 → Vertex 1 → Vertex 3 : Length 1+1=2
Query 3: Vertex 4 → Vertex 2 → Vertex 1 → Vertex 3 → Vertex 5 : Length 1+1+1+1=4
题意:给出一棵树,给每条边的权值,计算任意两结点经过k节点的最短路径,其实就是以k为根节点的LCA带权求和。
无聊跑了个从K点出发到所有节点的最短路,无伤大雅,最后把任意两个节点的最短路径加和即可。
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int maxn=1e5+10;
const LL inf=1000000000000000;
int n;
struct edge
{
int to;
LL val;
edge(){}
edge(int a,LL b)
{
to=a;
val=b;
}
};
vector<edge>mp[maxn];
bool vis[maxn];
LL dist[maxn];
void SPFA(int s)
{
queue<int>q;
while(!q.empty())q.pop();
for(int i=0;i<=n;i++)dist[i]=inf;
memset(vis,false,sizeof vis);
dist[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty())
{
int top=q.front();
q.pop();
vis[top]=false;
for(int i=0; i<mp[top].size(); i++)
{
int v=mp[top][i].to;
if(dist[v]>dist[top]+mp[top][i].val)
{
dist[v]=dist[top]+mp[top][i].val;
if(!vis[v])
{
vis[v]=true;
q.push(v);
}
}
}
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int from,to;
LL val;
for(int i=0;i<n-1;i++)
{
scanf("%d%d%d",&from,&to,&val);
mp[from].push_back(edge(to,val));
mp[to].push_back(edge(from,val));
}
int q,k;
scanf("%d%d",&q,&k);
SPFA(k);
for(int i=0;i<q;i++)
{
scanf("%d%d",&from,&to);
printf("%lld
",dist[from]+dist[to]);
}
}
}