AcWing 851. spfa求最短路
宋标 Lv5

题目

给定一个 个点 条边的有向图,图中可能存在重边和自环, 边权可能为负数

请你求出 号点到 号点的最短距离,如果无法从 号点走到 号点,则输出 impossible

数据保证不存在负权回路。

输入格式

第一行包含整数

接下来 行每行包含三个整数 ,表示存在一条从点 到点 的有向边,边长为

输出格式

输出一个整数,表示 号点到 号点的最短距离。

如果路径不存在,则输出 impossible

数据范围

,
图中涉及边长绝对值均不超过

输入样例:

3 3
1 2 5
2 3 -3
1 3 4

输出样例:

2

题解

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
62
63
64
65
66
67
68
69
#include <iostream>
#include <cstring>

using namespace std;

const int N = 100010, INF = 0x3f3f3f3f;

int h[N], e[N], w[N], ne[N], idx;
int q[N];
int n, m;
int dist[N];
bool st[N];

void add(int a, int b, int c)
{
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ;
}

void spfa()
{
memset(dist, 0x3f, sizeof dist);
dist[1] = 0;

int hh = 0, tt = 1;
q[tt ++] = 1;

while (hh < tt)
{
int t = q[++ hh];
if (hh == N) hh = 0;
st[t] = false;

for (int i = h[t]; ~i; i = ne[i])
{
int j = e[i];

if (dist[t] + w[i] < dist[j])
{
dist[j] = dist[t] + w[i];
if (!st[j])
{
q[tt ++] = j;
if (tt == N) tt = 0;
st[j] = true;
}
}
}
}
}

int main()
{
memset(h, -1, sizeof h);

cin >> n >> m;
while (m --)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c);
}

spfa();

if (dist[n] == INF) cout << "impossible" << endl;
else cout << dist[n] << endl;

return 0;
}
 评论