单源最短路径

单源最短路径

给定带权有向网络G=(V,E,W),每条边 e=<i,j>的权w(e)为非负实数,表示从i到j的距离。源点 s∈V。
求:从s出发到达其它结点的最短路径。

算法: dijkstra(v,[][]a,[]dist,[]prev)//Dijkstra算法
输入:
有向图G=(V,E,W),V={1,2,…,n}s=1
[][]a= {{},
{0,0,10,MAX,30,100},
{0,MAX,0,50,MAX,MAX},
{0,MAX,MAX,0,MAX,10},
{0,MAX,MAX,20,0,60},
{0,MAX,MAX,MAX,MAX,0}};

输出: prev[]中记录了每一结点的前一结点,依据每个结点对应前一结点值输出遍历全部结点的遍历顺序。

算法步骤:
·初始S={1}。
·对于i∈V-S,计算1到i的相对S的最短路,长度dist[i]。
·选择V-S中dist值最小的j,将j加入S,修改V-S中顶点的dist 值。
·继续上述过程,直到S=V为止。
具体程序操作过程为: (定义数组dist记录距离,prev记录前一个顶点)
·先计算出结点1到其他结点距离,找到与它最近的点单向连接起来。结点1已被用完记录为true
·从点2记录与它最近的点,连接…
·重复上述步骤。
·(在结果输出方面因为是记录的前一个结点是什么,本来想着是递归解决的,可是总是输出重复的1,没办法,只能多占用一些空间定义一个数组循环调用遍历记录值,然后倒序输出)

package 单源最小路径;

public class 单源最小路径 {
	public static void dijkstra(int v,float [][]a,float []dist,int []prev) {
		int n=dist.length-1;
		if(v<1||v>n)return;
		boolean []s =new boolean[n+1];
		for(int i=1;i<=n;i++)
		{
			dist[i]=a[v][i];
			s[i]=false;
			if(dist[i]==Float.MAX_VALUE)prev[i]=0;
			else prev[i]=v;
		}
		dist[v]=0;s[v]=true;
		for(int i=1;i<n;i++)
		{
			float temp=Float.MAX_VALUE;
			int u=v;
			for(int j=1;j<=n;j++)
				if((!s[j])&&(dist[j]<temp))
				{
					u=j;
					temp=dist[j];
				}
			s[u]=true;
			for(int j=1;j<=n;j++)
				if((!s[j])&&(a[u][j])<Float.MAX_VALUE)
				{
					float newdist=dist[u]+a[u][j];
					if(newdist<dist[j])
					{
						dist[j]=newdist;
						prev[j]=u;
					}
				}
		}
	}	
	public static void printit(int []prev,int n) {
		int []a =new int [10];
		int num=0;
		int q=0;
		for(int i=n;i>=1&&n!=1;i=prev[n])
		{
			if(i==1)q=1;
			a[num]=n;
			num++;
			n=prev[n];
			if(q==1)break;
		}
		System.out.print("1");
		for(int j=num-1;j>=0;j--)
		System.out.print("-->"+a[j]);
	}
	
	public static void main(String[] args) {
		String []V= {"v1","v2","v3","v4","v5"};
		float [][]a= {{},
					{ 0,0,10,Float.MAX_VALUE,30,100},
					{0,Float.MAX_VALUE,0,50,Float.MAX_VALUE,Float.MAX_VALUE},
					{0,Float.MAX_VALUE,Float.MAX_VALUE,0,Float.MAX_VALUE,10},
					{0,Float.MAX_VALUE,Float.MAX_VALUE,20,0,60},
					{0,Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE,Float.MAX_VALUE,0}};
		float []dist=new float [6];
		int []prev=new int[6];
		dijkstra(1,a,dist,prev);
		for(int i=1;i<6;i++)
		{
			printit(prev,i);
			System.out.println();
		}
	}
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值