zoukankan      html  css  js  c++  java
  • 图论基础算法

    在这里插入图片描述

    Dijkstra

    Dijkstra朴素版:将图中的点分为两个集合,一个集合为已经找到最短距离的点,另一个集合为还没有找到最短距离的点。初始化一个dis数组,dis[i]表示源点到i点的最短距离。外层循环n次,每次将一个点加入找到最短距离的集合。内层循环每次在未找到最短距离的集合中找到当前集合中距离源点最近的点,并用当前点去尝试更新其他点的最短距离。

    例题

    代码:

    import java.util.Scanner;
    
    public class Main{
        static int n,m,INF = 0x3f3f3f3f;
        static int[][] g = new int[550][550];
        static boolean[] flag = new boolean[550];
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            n = sc.nextInt();
            m = sc.nextInt();
            for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) if(i!=j) g[i][j] = INF;
            for(int i=0;i<m;i++){
                int x = sc.nextInt();
                int y = sc.nextInt();
                int z = sc.nextInt();
                g[x][y] = Math.min(g[x][y],z);
            }
            int res = fun();
            System.out.println(res);
        }
        public static int fun(){
            int[] dis = new int[n+5];
            for(int i=1;i<=n;i++) dis[i] = INF;
            dis[1] = 0;
            for(int i=0;i<n;i++){
                int t = -1;
                for(int j=1;j<=n;j++){
                    if(!flag[j]&&(t==-1||dis[t]>dis[j])) t = j;
                }
                flag[t] = true;
                for(int j=1;j<=n;j++) dis[j] = Math.min(dis[j],dis[t]+g[t][j]);
            }
            return dis[n]==INF?-1:dis[n];
        }
    }
    

    Dijkstra堆优化版本:采用优先队列优化,每次弹出距离源点最短距离的点,判断这个点是不是已经找到最短距离,如果已经找到了,忽略,否则用其更新他所能到的点,并将被更新的点加入队列。

    例题

    代码:

    import java.util.PriorityQueue;
    import java.util.Scanner;
    
    public class Main{
        static int index,n,m,INF=0x3f3f3f3f;
        static boolean[] flag = new boolean[200000];
        static int[] node = new int[200000],list = new int[200000],next = new int[200000],value = new int[200000];
        public static void main(String[] args){
            Scanner sc = new Scanner(System.in);
            n = sc.nextInt();
            m = sc.nextInt();
            for(int i=1;i<=n;i++) list[i] = -1;
            for(int i=0;i<m;i++){
                int x = sc.nextInt();
                int y = sc.nextInt();
                int z = sc.nextInt();
                add(x,y,z);
            }
            int res = fun();
            System.out.println(res);
        }
        public static int fun(){
            PriorityQueue<Node> queue = new PriorityQueue<>();
            queue.add(new Node(1,0));
            int[] dis = new int[n+5];
            for(int i=1;i<=n;i++) dis[i] = INF;
            dis[1] = 0;
            while(queue.size()>0){
                Node no = queue.poll();
                int id = no.id;
                int ds= no.dis;
                if(flag[id]) continue;
                flag[id] = true;
                for(int i=list[id];i!=-1;i=next[i]){
                    if(value[i]+dis[id]<dis[node[i]]){
                        dis[node[i]] = value[i]+dis[id];
                        queue.add(new Node(node[i],dis[node[i]]));
                    }
                }
            }
            return dis[n]>=INF/2?-1:dis[n];
        }
        public static void add(int a,int b,int c){
            node[index] = b;
            next[index] = list[a];
            value[index]= c;
            list[a] = index++;
        }
    }
    class Node implements Comparable<Node>{
        int id,dis;
    
        public Node(int id, int dis) {
            this.id = id;
            this.dis = dis;
        }
    
        public int compareTo(Node o) {
            return this.dis-o.dis;
        }
    }
    
  • 相关阅读:
    ES5 创建构造函数的私有属性
    js 触发打印操作
    创建 React 项目
    处理因使用 BigInt 等最新语法时 ts 编译报错
    TS 查找第三方声明文件
    Git 撤销工作区中的变动
    Git 查看文件修改状态
    Git 查看用户名和 Email
    查看某个 npm 包的所有发行版版本号,比如 vue
    Git 查看文件修改详情
  • 原文地址:https://www.cnblogs.com/fxzemmm/p/14847918.html
Copyright © 2011-2022 走看看