题目地址:
https://www.luogu.com.cn/problem/P3371
题目描述:
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入格式:
第一行包含三个整数
n
,
m
,
s
n,m,s
n,m,s,分别表示点的个数、有向边的个数、出发点的编号。接下来
m
m
m行每行包含三个整数
u
,
v
,
w
u,v,w
u,v,w,表示一条
u
→
v
u \to v
u→v的,长度为
w
w
w的边。
输出格式:
输出一行
n
n
n个整数,第
i
i
i个表示
s
s
s到第
i
i
i个点的最短路径,若不能到达则输出
2
31
−
1
2^{31}-1
231−1。
数据范围:
对于
20
%
20\%
20%的数据:
1
≤
n
≤
5
1≤n≤5
1≤n≤5,
1
≤
m
≤
1
1\le m \le 1
1≤m≤1;
对于
40
%
40\%
40%的数据:
1
≤
n
≤
100
1≤n≤100
1≤n≤100,
1
≤
m
≤
1
0
4
1\le m \le 10^4
1≤m≤104;
对于
70
%
70\%
70%的数据:
1
≤
n
≤
1000
1≤n≤1000
1≤n≤1000,
1
≤
m
≤
1
0
5
1\le m \le 10^5
1≤m≤105;
对于
100
%
100\%
100%的数据:
1
≤
n
≤
1
0
4
1 \le n \le 10^4
1≤n≤104,
1
≤
m
≤
5
×
1
0
5
1\le m \le 5\times 10^5
1≤m≤5×105,保证数据随机。
可以用Dijkstra算法来做。代码如下:
#include <iostream>
#include <cstring>
using namespace std;
typedef pair<int, int> PII;
const int N = 1e4 + 10, M = 5e5 + 10, INF = (1 << 31) - 1;
int n, m, S;
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++;
}
void dijkstra(int S) {
memset(dist, 0x3f, sizeof dist);
dist[S] = 0;
for (int i = 1; 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; j = ne[j]) {
int v = e[j];
if (!st[v] && dist[v] > dist[t] + w[j])
dist[v] = dist[t] + w[j];
}
}
}
int main() {
cin >> n >> m >> S;
memset(h, -1, sizeof h);
while (m--) {
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
}
dijkstra(S);
for (int i = 1; i <= n; i++)
if (dist[i] == 0x3f3f3f3f) cout << INF << ' ';
else cout << dist[i] << ' ';
cout << endl;
return 0;
}
时间复杂度 O ( n 2 ) O(n^2) O(n2),空间 O ( n ) O(n) O(n)。