Dijkstra模板(java)

Dijkstra模板

  • 再求单源最短路径时候,经常会用到Dijkstra算法,在某些数据量小的情况下bfs或者dfs或许可以得到结果,但是一旦结果大的时候常规搜索就很难在规定时间内得到答案。
  • Dijkstra基本思想:== 贪心==。Dijkstra其实就是一个在图论中的贪心算法。不过贪心的维度就是在预选点中的最短路径
  • Dijkstra算法的常规处理流程:
    1:首先,Dijkstra处理的是带正权值的有向图,那么,就需要一个二维数组(如果空间大用list数组)存储各个点到达的权值大小。
    2:其次,还需要一个boolean数组判断那些点已经确定,int数组记录长度。那些点没有确定。每次确定的点需要标记,如果遇到已经确定的点就不该抛入队列进行比较。
    3:需要优先队列抛入已经确定点的周围点。每次抛出确定最短路径的那个并且确定,直到所有点确定为止。
  • 简单的概括流程为:
    一:一般从选定点开始抛入优先队列。(路径一般为0),boolean标记0的位置,然后0周围的点抛入优先队列中(可能是node类),第一次就结束了
    二:从队列中抛出距离最近的那个点(目前是0周围邻居)这个点一定是最近的(所有权值都是正的,点的距离只能越来越长。)标记这个点为true,并且将这个点的邻居加入队列,那么下次点一定在这个点的邻居和以前的点中产生。并且我们只能确定这个队列中只有一个最近点,因为有可能第二最近的就是被确定点的邻居。所以每次只能确定一个点,知道确定所有点。
    三:重复二的操作,直到所有点都确定。
    代码为:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
//n 个定点 m条边的图
public class Main{
	static int leng[];
	public static void main(String[] args) throws IOException {
		// TODO 自动生成的方法存根
		StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int n=(int)in.nval;in.nextToken();int m=(int)in.nval;
		int map[][]=new int[n][n];
		boolean bool[][]=new boolean[n][n];
		List<Integer>list[]=new ArrayList[n];
		for(int i=0;i<n;i++)
		{
			list[i]=new ArrayList<>();
		}
	    leng=new int[n];//记录长度
		boolean jud[]=new boolean[n];
		for(int i=1;i<n;i++) {leng[i]=Integer.MAX_VALUE;}
		for(int i=0;i<m;i++)
		{
			in.nextToken();int u=(int)in.nval;
			in.nextToken();int v=(int)in.nval;
			in.nextToken();int l=(int)in.nval;
			map[u-1][v-1]=l;
			list[u-1].add(v-1);
			bool[u-1][v-1]=true;//两点联通 
		}
		Queue<Integer>q1=new PriorityQueue<>(compare);
		q1.add(0);
		int count=0;
		while(!q1.isEmpty())
		{
			int x=q1.poll();
			if(count>=n) {break;}//所有点都确定
			if(!jud[x])
			{
				jud[x]=true;count++;
				for(int i=0;i<list[x].size();i++)//遍历
				{
					if(bool[x][list[x].get(i)]&&!jud[list[x].get(i)])//有路径并且未被确定
					{
						if(leng[list[x].get(i)]==Integer.MAX_VALUE) //第一次加入,更新路径
						{leng[list[x].get(i)]=leng[x]+map[x][list[x].get(i)];q1.add(list[x].get(i));}
						else if(leng[list[x].get(i)]>leng[x]+map[x][list[x].get(i)])
						{
							leng[list[x].get(i)]=leng[x]+map[x][list[x].get(i)];						
						}
						//System.out.println( no.leng+map[no.x][i]);
					}
				}
			}
		}
		for(int i=1;i<n;i++)//依次输出最近点
		{
			out.println(leng[i]);
		}
		out.flush();
	}
static Comparator<Integer>compare=new Comparator<Integer>() {

	@Override
	public int compare(Integer o1, Integer o2) {
		return leng[o1]-leng[o2];
	}	
};
	static class node
	{
		int x;int leng;
		public node(int x,int leng)
		{
			this.x=x;
			this.leng=leng;
		}
	}
}
    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/qq_40693171/article/details/83586211
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞