问题描述
给定一个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代码:
#include<iostream>
#include<string.h>
#include<queue>
using namespace std;
struct node{
int e,next,val;
}edge[];
int M=,N,head[],m;
bool v[];
void add(int s,int e,int val){
edge[++M].e=e;
edge[M].val=val;
edge[M].next=head[s];
head[s]=M;
}
int lowCost[];
void bellman(int s){
for(int i=;i<=N;i++){
lowCost[i]=;
v[i]=;
}
queue<int> q;
lowCost[s]=;
q.push(s);
v[s]=;
while(!q.empty()){
int u=q.front();q.pop();
v[u]=;
for(int i=head[u];i!=-;i=edge[i].next){
int no=edge[i].e;
int val=edge[i].val;
if(lowCost[u]+val<lowCost[no]&&!v[no]){
lowCost[no]=lowCost[u]+val;
v[no]=;
q.push(no);
}
}
}
}
int main(){
cin>>N>>m;
int s,e,v;
memset(head,-,sizeof(head));
for(int i=;i<=m;i++){
cin>>s>>e>>v;
add(s,e,v);
}
bellman();
for(int i=;i<=N;i++){
cout<<lowCost[i]<<endl;
}
return ;
}