题目背景
本题测试数据为随机数据,在考试中可能会出现构造数据让SPFA不通过,如有需要请移步 P4779。
题目描述
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
输入格式
第一行包含三个整数 n,m,sn,m,sn,m,s,分别表示点的个数、有向边的个数、出发点的编号。
接下来 mmm 行每行包含三个整数 u,v,wu,v,wu,v,w,表示一条 u→vu \to vu→v 的,长度为 www 的边。
输出格式
输出一行 nnn 个整数,第 iii 个表示 sss 到第 iii 个点的最短路径,若不能到达则输出 231?12^{31}-1231?1。
输入输出样例
输入 #1
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
输出 #1
0 2 4 3
说明/提示
【数据范围】
对于 20%20%20% 的数据:1≤n≤51\le n \le 51≤n≤5,1≤m≤151\le m \le 151≤m≤15;
对于 40%40%40% 的数据:1≤n≤1001\le n \le 1001≤n≤100,1≤m≤1041\le m \le 10^41≤m≤104;
对于 70%70%70% 的数据:1≤n≤10001\le n \le 10001≤n≤1000,1≤m≤1051\le m \le 10^51≤m≤105;
对于 100%100%100% 的数据:1≤n≤1041 \le n \le 10^41≤n≤104,1≤m≤5×1051\le m \le 5\times 10^51≤m≤5×105,保证数据随机。
对于真正 100%100%100% 的数据,请移步 P4779。请注意,该题与本题数据范围略有不同。
#include <iostream>
#include <algorithm>
#include <climits>
#include <cmath>
using namespace std;const int inf = 1e9;
const int maxn = 5e5 + 10;
struct node{
int v;int len;int nex;
}edge[maxn << 1];
int d[maxn];
bool vis[maxn];
int head[maxn];
int n, m, s;
int cnt;void add_edge(int u, int v, int w) {
edge[++cnt].v = v;edge[cnt].len = w;edge[cnt].nex = head[u];head[u] = cnt;
} void Dijkstra() {
fill(d, d + n + 1, inf);d[s] = 0;for(int i = 1; i <= n; i++) {
int min_num = inf, id = -1;for(int j = 1; j <= n; j++) {
if(min_num > d[j] && vis[j] == false) min_num = d[j], id = j;}if(id == -1) return;vis[id] = true;
// cout << id << " " << d[id] << endl;for(int j = head[id]; j; j = edge[j].nex) {
int v = edge[j].v;
// cout << edge[j].v << " " << edge[j].len << ' ' << d[j] << " " << j << ' ' << d[v] << endl;if(d[v] >= d[id] + edge[j].len) {
d[v] = d[id] + edge[j].len;}}}
}int main() {
int u, v, w;cin >> n >> m >> s;for(int i = 1; i <= m; i++) {
cin >> u >> v >> w;add_edge(u, v, w);
// add_edge(v, u, w);}Dijkstra();for(int i = 1; i <= n; i++) {
if(d[i] == inf) cout << INT_MAX << " ";else cout << d[i] << " ";}return 0;
}