算法训练 最短路  
时间限制: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


/*
题解:SPFA解法,但正确率只有80%啊 啊~
*/ 

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
const int N=20010;
int n,dis[N],vis[N];
struct node{
int to,w,next;
}edge[N];

int cnt=0,head[N];
void addedge(int i,int j,int w){
edge[cnt].to=j;
edge[cnt].w=w;
edge[cnt].next=head[i];
head[i]=cnt++;
}
void spfa(int s){
for(int i=1; i<=n; i++){
dis[i]=inf;
vis[i]=0;
}
queue<int> q;
q.push(s);
dis[s]=0,vis[s]=1;
while(!q.empty()){
int x=q.front();
q.pop();
vis[x]=0;
for(int k=head[x];k!=-1; k=edge[k].next){
int t=edge[k].to;
if(dis[t]>dis[x]+edge[k].w){
dis[t]=dis[x]+edge[k].w;
if(!vis[t]){
q.push(t);
vis[t]=1;
}
}
}
}
}

int main(){
int m,u,v,l;
scanf("%d %d",&n,&m);
memset(head,-1,sizeof(head));
for(int i=1; i<=m; i++){
scanf("%d %d %d",&u,&v,&l);
addedge(u,v,l);
}
spfa(1);
for(int i=2; i<=n; i++){
printf("%d\n",dis[i]);
}
// while(1);
}