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