资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
给定一个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 -1
2 3 -1
3 1 2
样例输出
-1
-2
-2
数据规模与约定
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。
本题是单源点最短路径问题,存在负边但不存在负环,可以用bellman算法。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 #define INF 0x3f3f3f3f 6 7 using namespace std; 8 const int max_v=20007; 9 const int max_e=200007; 10 int dis[max_v]; 11 12 struct edge { 13 int from, to, cost; 14 }e[max_e]; 15 int n, m;//顶点数,边数 16 17 void bellman(int s) {//传入单源点 18 memset(dis, INF, sizeof(dis)); 19 dis[s]=0; 20 while(true) { 21 bool update=false; 22 for(int i=0; i<m; i++) { 23 edge ee=e[i]; 24 if(dis[ee.from]!=INF && dis[ee.to]>(dis[ee.from]+ee.cost)) { 25 dis[ee.to]=dis[ee.from]+ee.cost; 26 update=true; 27 } 28 } 29 if(!update) break; 30 } 31 return; 32 } 33 34 int main() { 35 int u, v, l; 36 cin>>n>>m; 37 for(int i=0; i<m; i++) { 38 scanf("%d %d %d", &u, &v, &l); 39 e[i].from=u; 40 e[i].to=v; 41 e[i].cost=l; 42 } 43 bellman(1); 44 for(int i=2; i<=n; i++) { 45 printf("%d ", dis[i]); 46 } 47 return 0; 48 }