AtCoder Beginner Contest 070 Transit Tree Path(一道鸡贼的最短路径题)

D - Transit Tree Path
Time limit : 2sec / Memory limit : 256MB


Score : 400 points


Problem Statement
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
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
Output
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.

如题,最短路径,只是是必经过点到任一点的最短路径;

不多bb,代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>
#include <vector>
#include <queue>
using namespace std;
const int N=1e5+10,INF=0x3f3f3f3f;
typedef pair<int,int>P; 
typedef vector<int>::iterator ive;
long long step[N];//步数,这里是权重 
int k;
map<int,vector<int> >m;
map<P,int>mmp;/* P是点 ,int是亮点之间的权值*/
void bfs()//以k为始,队列存点,遍历全部,广搜深搜都可以
{
    queue<int>q;
    q.push(k);
    step[k]=0;
    while(!q.empty()){
        int now=q.front();
        q.pop();
        for(ive it=m[now].begin();it!=m[now].end();it++){
            if(step[now]+mmp[P(max(*it,now),min(*it,now))]<step[*it])//条件:预防以前的路再走一遍 ,如果有更省权重的方案,就更新 
	{
                step[*it]=step[now]+mmp[P(max(*it,now),min(*it,now))];
                q.push(*it);
            }
 
 
        }
    }
}
int main()
{
    int n,a,b,c,q,x,y;
    while(~scanf("%d",&n)){
        memset(step,INF,sizeof(step));
        m.clear();
        mmp.clear();
        n--;
        while(n--){
            scanf("%d%d%d",&a,&b,&c);
            m[a].push_back(b);//存路径 ,因为是互通的,所以正反都存 
            m[b].push_back(a);
            mmp[P(max(a,b),min(a,b))]=c;//存权重,节省空间,规定大的在前小的在后 
        }
        scanf("%d%d",&q,&k);
        bfs();
        while(q--){
            scanf("%d%d",&x,&y);
            printf("%lld\n",step[x]+step[y]);
        }
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值