UPC-6690 Transit Tree Path(树上最短路径SPFA)

题目描述
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\n",dist[from]+dist[to]);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/kuronekonano/article/details/81354266
今日推荐