问题描述
给定一个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
由于有负边,所以Dijkstra算法无法使用,而Floyd算法的效率太低,容易超时,所以使用Bellman(SPFA)来计算这道题
这是我的ac代码:
1 #include<iostream> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 struct node{ 6 int e,next,val; 7 }edge[200010]; 8 int M=0,N,head[20010],m; 9 bool v[20010]; 10 void add(int s,int e,int val){ 11 edge[++M].e=e; 12 edge[M].val=val; 13 edge[M].next=head[s]; 14 head[s]=M; 15 } 16 int lowCost[20010]; 17 void bellman(int s){ 18 for(int i=1;i<=N;i++){ 19 lowCost[i]=99999999; 20 v[i]=0; 21 } 22 queue<int> q; 23 lowCost[s]=0; 24 q.push(s); 25 v[s]=1; 26 while(!q.empty()){ 27 int u=q.front();q.pop(); 28 v[u]=0; 29 for(int i=head[u];i!=-1;i=edge[i].next){ 30 int no=edge[i].e; 31 int val=edge[i].val; 32 if(lowCost[u]+val<lowCost[no]&&!v[no]){ 33 lowCost[no]=lowCost[u]+val; 34 v[no]=1; 35 q.push(no); 36 } 37 } 38 } 39 } 40 int main(){ 41 cin>>N>>m; 42 int s,e,v; 43 memset(head,-1,sizeof(head)); 44 for(int i=1;i<=m;i++){ 45 cin>>s>>e>>v; 46 add(s,e,v); 47 } 48 bellman(1); 49 for(int i=2;i<=N;i++){ 50 cout<<lowCost[i]<<endl; 51 } 52 return 0; 53 }