问题描述
给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。
输入格式
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
输出格式
共n-1行,第i行表示1号点到i+1号点的最短路。
样例输入
3 3
1 2 -1
2 3 -1
3 1 2
样例输出
-1
-2
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。
分析:1.n个点,m条有向边,含有负边
1.外层循环n-1次,内层循环m次,进行松弛
3.添加check变量判断本轮是否进行松弛了,如果未进行松弛则可以提前退出循环(否则会超时)
4.处理有向边时,注意u[i]和v[i]的顺序不要颠倒~
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#include <iostream> using namespace std; int main() { int dis[20001] = {0}, u[200001], v[200001],w[200001]; int n, m, inf = 99999999; fill(dis+2,dis+20001,inf); scanf("%d %d", &n, &m); for(int i = 1; i <= m; i++) scanf("%d %d %d",&u[i], &v[i], &w[i]); for(int k = 1; k <= n - 1; k++){ int check = 0; for(int i = 1; i <= m; i++){ if(dis[v[i]] > dis[u[i]] + w[i]){ dis[v[i]] = dis[u[i]] + w[i]; check = 1; } } if(check == 0) break; } for(int i = 2; i <= n; i++) printf("%d\n",dis[i]); return 0; } |
❤ 点击这里 -> 订阅《PAT | 蓝桥 | LeetCode学习路径 & 刷题经验》by 柳婼