给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。
输入格式
第一行包含整数n和m。
接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。
输出格式
输出一个整数,表示1号点到n号点的最短距离。
如果路径不存在,则输出-1。
数据范围
1≤n≤500,
1≤m≤105,
图中涉及边长均不超过10000。
输入样例:
输出样例
模板
针对稠密图用领接矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
| #include <iostream> #include <cstring> #include <algorithm>
using namespace std;
const int N = 510;
int n, m; int g[N][N]; int dist[N]; bool st[N];
int dijkstra() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; for(int i = 0; i < n; i ++) { int t = -1; for(int j = 1; j <= n; j ++) if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j; st[t] = true; for(int j = 1; j <= n; j ++) dist[j] = min(dist[j], dist[t] + g[t][j]); } if(dist[n] == 0x3f3f3f3f) return -1; else return dist[n]; }
int main() { cin >> n >> m; memset(g, 0x3f, sizeof g); while(m --) { int a, b, c; cin >> a >> b >> c; g[a][b] = min(g[a][b], c); } cout << dijkstra() << endl; return 0; }
|
针对稀疏图用邻接表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include <iostream> #include <algorithm> #include <cstring>
using namespace std;
const int N = 510, M = 1e5 + 10;
int n, m; int h[N], e[M], ne[M], w[M], idx; int dist[N]; bool st[N];
void add(int a, int b, int c) { e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++; }
int dijkstra() { memset(dist, 0x3f, sizeof dist); dist[1] = 0; for (int i = 0; i < n; i ++) { int t = -1; for (int j = 1; j <= n; j ++) if (!st[j] && (t == -1 || dist[t] > dist[j])) t = j; st[t] = true; for (int j = h[t]; j != -1; j = ne[j]) { int k = e[j]; if (dist[k] > dist[t] + w[j]) dist[k] = dist[t] + w[j]; } } if (dist[n] == 0x3f3f3f3f) return -1; else return dist[n]; }
int main() { cin >> n >> m; memset(h, -1, sizeof h); while(m --) { int a, b, w; cin >> a >> b >> w; add(a, b, w); } cout << dijkstra() << endl; return 0; }
|