Problem Description
有n个城市,m条交通路径,每条交通路径都是单行道。他已经预先规划好了一些点作为旅游的起点和终点,他想选择其中一个起点和一个终点,并找出从起点到终点的一条路线亲身体验浪的过程。但是他时间有限,所以想选择耗时最小的,你能告诉他最小的耗时是多少吗?
Input
包含多组测试数据。
输入第一行包括两个整数n和m,表示有n个地点,m条可行路径。点的编号为1 - n。
接下来m行每行包括三个整数i, j, cost,表示从地点i到地点j需要耗时cost。
接下来一行第一个数为S,表示可能的起点数,之后S个数,表示可能的起点。
接下来一行第一个数为E,表示可能的终点数,之后E个数,表示可能的终点。
0<S, E≤n≤100000,0<m≤100000,0<cost≤100。
Output
输出他需要的最短耗时。
Sample Input
4 4
1 3 1
1 4 2
2 3 3
2 4 4
2 1 2
2 3 4
1 3 1
1 4 2
2 3 3
2 4 4
2 1 2
2 3 4
Sample Output
1
这一题的只比裸dijkstra多了一个---把图存完后,给出S个可能的起点,E个可能的终点,从中选出一个起点和终点,使得路径最短。
就是一个小敲门
把 0 作为超级源点, n+1 作为超级终点 ,
每个可能的起点与0相连,权值为0,
每个可能的终点与 n+1 相连,权值为0,
直接dijkstra。
输出 dis[ n+1 ]~~~~~~
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstring>
#include <cstdio>
using namespace std;
typedef pair<int, int> P; //first是最短距离,second 是顶点的编号
const int maxn = 100010;
const int INF = 0x3f3f3f3f;
struct Edge
{
int to,val;
};
int N;
int dis[maxn]; //记录各个点到源点的距离
vector<Edge> G[maxn]; // vector 存图,比如G[2] 后面存的是 与 点 2 有联系的点 和 权值。
void dijkstra(int s) //s 是源点
{
// que 是一个pair<>类型的优先队列
priority_queue<P, vector<P>, greater<P> > que; //通过指定greater<P>参数,堆按照first从小到大的顺序取出值
memset(dis,INF,sizeof(dis));
dis[s] = 0; // 源点到源点的距离为0
que.push(P(0,s)); //先把源点放入队列,从源点来时操作
while(!que.empty()) //当队列不为空时
{
P T = que.top(); //q.top(). first 就是离源点最近的点,用 T 记录下来
que.pop(); // 记录下来之后,q.top()可以出队了、
int a = T.second; //当前离源点最近的点的编号
if(dis[a] != T.first)
continue;
for(int i = 0;i < G[a].size();i ++)
{
Edge e = G[a][i]; // G[a][i] 存的是a 点的一个出边 有 to 和 val 两个值。
if(dis[e.to] > dis[a] + e.val)
{
dis[e.to] = dis[a] + e.val;
que.push(P(dis[e.to],e.to));
}
}
}
}
int y1[1000000];
int main()
{
int n,m;
int x,y; //x个起点,y个终点
int a;
Edge b;
while(scanf("%d %d",&n,&m)!=EOF)
{
for(int i = 0;i < m;i ++)
{
scanf("%d %d %d",&a,&b.to,&b.val);
G[a].push_back(b);
}
scanf("%d",&x);
for(int i = 0;i < x;i ++) //把 0 作为超级源点
{
scanf("%d",&b.to);
b.val = 0;
G[0].push_back(b);
}
scanf("%d",&y);
b.to = n+1;
b.val = 0;
for(int i = 0;i < y;i ++) //把 n + 1 作为超级终点。
{
int end;
scanf("%d",&end);
G[end].push_back(b);
}
dijkstra(0);
cout<<dis[n+1]<<endl;
for(int i = 0;i <= n;i ++)
G[i].clear();
}
return 0;
}