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
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞