问题描述
给定一个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,保证从任意顶点都能到达其他所有顶点。
import java.io.*;
import java.util.*;
class Main
{
static int n,m;
static int[] u;
static int[] v;
static int[] w;
static int[] d;
static int[] first;
static int[] next;
static Queue<Integer> q=new LinkedList<Integer>();
static boolean[] inq;
public static void main(String[] args) throws IOException
{
int i;
BufferedReader bfr=new BufferedReader(new InputStreamReader(System.in));
String str = bfr.readLine();
String[] s = str.split("\\s");
n=Integer.parseInt(s[0]);
m=Integer.parseInt(s[1]);
n++;
m++;
u=new int[m];
v=new int[m];
w=new int[m];
first=new int[n];
next=new int[m];
d=new int[n];
inq=new boolean[n];
for(i=1;i<n;i++)
first[i]=-1;
for(i=1;i<m;i++)
{
str = bfr.readLine();
s = str.split(" ");
u[i]=Integer.parseInt(s[0]);
v[i]=Integer.parseInt(s[1]);
w[i]=Integer.parseInt(s[2]);
next[i]=first[u[i]];
first[u[i]]=i;
}
spfa(1);
for(i=2;i<n;i++)
System.out.println(d[i]);
}
public static void spfa(int s)
{
int i,x;
for(i=2;i<n;i++)
d[i]=Integer.MAX_VALUE;
q.offer(s);
while(!q.isEmpty())
{
x=q.poll();
inq[x]=false;
for(i=first[x];i!=-1;i=next[i])
if(d[v[i]]>d[x]+w[i])
{
d[v[i]]=d[x]+w[i];
if(!inq[v[i]])
{
inq[v[i]]=true;
q.offer(v[i]);
}
}
}
}
}