登录后才能查看试题。
算法训练 最短路
时间限制:1.0s 内存限制:256.0MB
锦囊1
锦囊2
锦囊3
问题描述
给定一个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,保证从任意顶点都能到达其他所有顶点。
易超时,但是用了StringTokenizer后果断100%,代码有些长,但是运行起来还不错350毫秒
import java.io.*; import java.util.*; public class 蓝桥杯最短路 { static int n,m,MAX = 10000000; static boolean vis[]; static int dis[]; static Queue<Integer> que; static int u[],v[],w[],first[],next[]; public static void main(String[] args) throws IOException { BufferedReader br=new BufferedReader(new InputStreamReader(System.in)); //Scanner sc = new Scanner(new InputStreamReader(System.in)); StringTokenizer tok= new StringTokenizer(""); while(!tok.hasMoreTokens()) tok=new StringTokenizer(br.readLine()); int n=Integer.parseInt(tok.nextToken()); while(!tok.hasMoreElements()) tok=new StringTokenizer(br.readLine()); int m=Integer.parseInt(tok.nextToken()); dis = new int[n+1]; vis = new boolean[n+1]; u = new int[m+1]; v = new int[m+1]; w = new int[m+1]; first = new int[n+1]; next = new int [m+1]; for(int i=1;i<=n;i++){ first[i] = -1; dis[i] = MAX; } for(int i=1;i<=m;i++){ while(!tok.hasMoreElements())tok=new StringTokenizer(br.readLine()); u[i] = Integer.parseInt(tok.nextToken()); while(!tok.hasMoreElements()) tok=new StringTokenizer(br.readLine()); v[i] = Integer.parseInt(tok.nextToken()); while(!tok.hasMoreElements()) tok = new StringTokenizer(br.readLine()); w[i] = Integer.parseInt(tok.nextToken()); next[i] = first[u[i]]; first[u[i]] = i;//逆邻接表表示法,速度! } spfa(); for(int i=2;i<=n;i++) System.out.println(dis[i]) ; } private static void spfa() { dis[1] = 0; que = new PriorityQueue<Integer>(); que.clear(); que.offer(1); while(!que.isEmpty()){ int x = que.poll(); vis[x] = false; for(int e=first[x]; e!=-1; e=next[e]){ int temp = dis[x]+w[e]; if(dis[v[e]]>temp){//松弛操作 dis[v[e]] = temp; if(!vis[v[e]]){ que.offer(v[e]); vis[v[e]] = true; } } } } } }