现在的位置: 首页 > 综合 > 正文

蓝桥杯 最短路(spfa(优先队列+迪杰斯特拉))

2014年09月04日 ⁄ 综合 ⁄ 共 1877字 ⁄ 字号 评论关闭

登录后才能查看试题。
  算法训练 最短路  
时间限制: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
数据规模与约定

对于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;
        			   }
        		   }
        	   }
           }
		}
	}

抱歉!评论已关闭.