dijkstra算法求解单源点最短路径

package aaa;

import java.util.*;

public class Main {
    static Scanner in = new Scanner(System.in);
    static final int INF = 0x3f3f3f3f;
    static final int MAXN = 110;
    static int matrix[][] = new int[MAXN][MAXN];  
    static boolean[] vis = new boolean[MAXN];
    static int[] dis = new int [MAXN];
    static int[] vetex=  new int[MAXN];  
	static int n, e, s, t, w, k, min; 
	static void dijkstra(int v){
        //初始化dis数组和vis数组
		for (int i = 0; i < n; i++) {
			//以v为原点有路径可达,并且不是v本身,dis设置为初始值
			if(matrix[v][i]>0&&v!=i)
			    dis[i]=matrix[v][i];
			else
				dis[i]=INF;	
			
			vis[i]=false;
			dis[v]=0;
		}
		vis[v]=true;
		//循环n-1次,依次求解各个路径
		for (int i = 1; i < n; i++) {
			min=INF;
			k=0;
			//求解从原点到所有点里面路径值最小的那个点,贪心思想
			for (int j = 0; j < n; j++) {
			   if(!vis[j]&&dis[j]<min){
					min=dis[j];//更新最小值
					k=j;//更新顶点值
				}
			}
		    vis[k]=true;//将新得到的顶点纳入最小顶点集
		    //从新的顶点集开始寻找下一个最短路径
			for (int j = 0; j < n; j++) {
				if(!vis[j]&&matrix[k][j]>0&&min+matrix[k][j]<dis[j]){
					dis[j]=min+matrix[k][j];//更新最小路径
				}
			  }
		  }
	}
	public static void main(String[] args) {
		Arrays.fill(dis, INF);
		while(in.hasNext()){
			 n  =in.nextInt();
			 e = in.nextInt();
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					matrix[i][j]=0;
				}
			}
            for (int i = 0; i < e; i++) {
				s=in.nextInt();
				t=in.nextInt();
				w=in.nextInt();
				matrix[s][t]=w;
			}
            dijkstra(0);//此处要保证输入的顶点值是对所有顶点均可达的
         for (int i = 0; i < n; i++) {
			System.out.println(dis[i]);
		  }
	  }
	}
}

 

优化:使用优先队列保存最小的值,每次直接从队头取出元素即可。实质建立维护一个小顶堆。

import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;

public class Main {
	static Scanner in = new Scanner(System.in);
	static int n,e;;
	static int[] dis = new int[10000+5];
	static int[][] mp = new int[1000+5][1000+5];
	static boolean[] vis = new boolean[10000+5];
	static void dijlstra() {
		PriorityQueue<Node> p = new PriorityQueue<Node>(new Comparator<Node>() {
			@Override
			public int compare(Node o1, Node o2) {
				return o1.len-o2.len;//距离近的在前面
			}
		});
		dis[1] = 0;
		Node o = new Node(1,dis[1]);
		p.add(o);
		while(!p.isEmpty()) {
			Node te = p.poll();
//			System.out.println(te.v+" "+te.len);
			if(vis[te.v]) continue;
			vis[te.v] = true;
			for (int i = 1; i <= n; i++) {
				if(!vis[i]&&mp[te.v][i]!=0&&te.len+mp[te.v][i]<dis[i]) {
					dis[i] = te.len+mp[te.v][i];
                     p.add(new Node(i,dis[i]));
				}
			}
		}
	}
	public static void main(String[] args) {
        n = in.nextInt();
        e = in.nextInt();
        for (int i = 1; i <= e; i++) {
			mp[in.nextInt()][in.nextInt()] = in.nextInt();
		}
        Arrays.fill(vis, 0,n+1,false);
        Arrays.fill(dis, 0,n+1,Integer.MAX_VALUE);
        dijlstra();
        for (int i = 1; i <= n; i++) {
			System.out.print(dis[i]+" ");
		}
        System.out.println();
	}
}
class Node{
	int v,len;
	Node(int v,int dis){
		this.v = v;
		this.len = dis;
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值