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;
}