标签:
5 8 5 1 2 2 1 5 3 1 3 4 2 4 7 2 5 6 2 3 5 3 5 1 4 5 1 2 2 3 4 3 4 1 2 3 1 3 4 2 3 2 1 1
1 -1
题意:一个人,要坐公交去上班。一直有n各站点,m条路线,已知他可以从w各站点出发坐车,求到达目的地s所用的最少时间。如不能到达,则输出-1。
解析:Dijkstra算法,不过直接使用w次Dijkstra,会超时的。下面有两个思路:
1.将这个人的位置设为站点0,然后将站点0和那w个出发点连接在一起,相当于从他家到这些站点的时间为0。然后再使用Dijkstra,输出d[s]即可。
2.利用反向图,因为可以有多个起点,但是只有一个终点,所以反向图的话,相当于只有一个起点,好多个终点了,这样只要使用一次Dijkstra,然后输出w个起点中的最小值即可。
PS:一定要注意公交线路是单向的,一定要建成有向图!!!
AC代码:
思路一
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; #define INF 1e7 + 2 const int maxn = 1000 + 5; int n, m; int w[maxn][maxn], d[maxn], v[maxn]; void dijkstra(int s){ memset(v, 0, sizeof(v)); for(int i=0; i<=n; i++) d[i] = w[s][i]; d[s] = 0; v[s] = 1; for(int i=0; i<=n; i++){ int x, m = INF; for(int y=0; y<=n; y++) if(!v[y] && d[y] <= m) m = d[x = y]; if(m == INF) break; v[x] = 1; for(int y=0; y<=n; y++) d[y] = min(d[y], d[x] + w[x][y]); } } int main(){ #ifdef sxk freopen("in.txt", "r", stdin); #endif //sxk int x, y, z, s, t; while(scanf("%d%d%d", &n, &m, &s)!=EOF){ for(int i=0; i<=n; i++) for(int j=0; j<=n; j++) w[i][j] = (i==j ? 0 : INF); for(int i=0; i<m; i++){ scanf("%d%d%d", &x, &y, &z); w[x][y] = min(w[x][y], z); } scanf("%d", &t); while(t--){ scanf("%d", &x); w[0][x] = 0; } dijkstra(0); printf("%d\n", d[s] == INF ? -1 : d[s]); } return 0; }
思路二
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std; #define INF 1e7 + 2 const int maxn = 1000 + 5; int n, m; int w[maxn][maxn], d[maxn], v[maxn]; void dijkstra(int s){ memset(v, 0, sizeof(v)); for(int i=0; i<=n; i++) d[i] = w[s][i]; d[s] = 0; v[s] = 1; for(int i=0; i<=n; i++){ int x, m = INF; for(int y=0; y<=n; y++) if(!v[y] && d[y] <= m) m = d[x = y]; if(m == INF) break; v[x] = 1; for(int y=0; y<=n; y++) d[y] = min(d[y], d[x] + w[x][y]); } } int main(){ #ifdef sxk freopen("in.txt", "r", stdin); #endif //sxk int x, y, z, s, t; while(scanf("%d%d%d", &n, &m, &s)!=EOF){ for(int i=0; i<=n; i++) for(int j=0; j<=n; j++) w[i][j] = (i==j ? 0 : INF); for(int i=0; i<m; i++){ scanf("%d%d%d", &x, &y, &z); w[y][x] = min(w[y][x], z); //处理成反向图 } dijkstra(s); scanf("%d", &t); int ans = INF; while(t--){ scanf("%d", &x); ans = min(ans, d[x]); //找最小值 } printf("%d\n", ans == INF ? -1 : ans); } return 0; }
hdu 2680 Choose the best route (Dijkstra & 反向图)
标签:
原文地址:http://blog.csdn.net/u013446688/article/details/42915199