最短路

SPFA算法详解与Java实现

算法思想:我们用数组d记录每个结点的最短路径估计值。我们采取的方法是动态逼近法:设立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止

  建议先看spfa详解: http://blog.youkuaiyun.com/muxidreamtohit/article/details/7894298

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class Main {
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();//顶点数
		int m = sc.nextInt();//边数
		
		int[] num = new int[n+1];//每个顶点边的个数 
		
		Eage[][] eage= new Eage[n+1][m];
		
		for(int i = 0 ; i < m ; i++ ){
			int u = sc.nextInt();//始点
			int v = sc.nextInt();//终点
			int l = sc.nextInt();//权值
			eage[u][num[u]++] = new Eage(v,l);
		}
		
		int[] d = new int[n+1];//最短距离
		init(n, d);//对最小边初始化
		boolean visit[] = new boolean[n+1];//是否在队列中
		spfa(visit, num, d, eage);
		for(int i = 2 ; i <= n ; i++ ){
			System.out.println(d[i]);
		}
	
	}
	public static void spfa(boolean[] visit,int[] num,int d[],Eage[][] eage){
		Queue<Integer> q = new LinkedList<Integer>();
		q.offer(1);//先在队列中插入第一个元素1
		visit[1] = true;
		while(!q.isEmpty()){
			int x = q.poll();//弹出队首元素
			visit[x] = false;
			for(int i = 0 ; i < num[x] ; i++ ){
				if(d[x] != Integer.MAX_VALUE && d[eage[x][i].getTo()]>eage[x][i].getCost()+d[x]){
					d[eage[x][i].getTo()] = eage[x][i].getCost()+d[x];
					if(!visit[eage[x][i].getTo()]){//如果v点不在队列中,就将v点放入队尾。
						q.offer(eage[x][i].getTo());
						visit[eage[x][i].getTo()] = true;
					}
				}
			}
		}
		
	}
	public static void init(int n,int[] d){
		for(int i = 1; i <= n ; i++){
			d[i] = Integer.MAX_VALUE;
		}
		d[1] = 0;
	}
	
	
	
}
class Eage{
	int to;
	int cost;
	public int getTo() {
		return to;
	}
	public void setTo(int to) {
		this.to = to;
	}
	public int getCost() {
		return cost;
	}
	public void setCost(int cost) {
		this.cost = cost;
	}
	public Eage(int to ,int cost) {
		// TODO Auto-generated constructor stub
		this.to = to;
		this.cost = cost;
	}
}








注:在蓝桥杯上跑总是有一部分运行超时。

总结:1、关于图的构建还是太陌生。

    2、Queue的offer()  进队列,poll()出队列(先进先出)   还有一个优先级队列  (http://blog.youkuaiyun.com/hiphopmattshi/article/details/7334487)

   3、(最重要的)spfa算法详解 http://blog.youkuaiyun.com/muxidreamtohit/article/details/7894298,java代码实现http://www.cnblogs.com/dashen/p/3755049.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值