面试常规算法复习(最短路)

两种常规的最短路(floyd就不写了)



package com.company;

import java.util.Comparator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;



class Node{
    private int val;
    private int id;
    Node(int val, int id){
        this.id = id;
        this.val = val;
    }

    public int getId() {
        return id;
    }

    public int getVal() {
        return val;
    }

    public void setVal(int val) {
        this.val = val;
    }
}


public class Main {

    public static void main(String[] args) {
        int w[][] = new int[505][505];
        int INF = 0x3f3f3f3f;
//        System.out.println(INF);
        int n, m;
        Scanner in = new Scanner(System.in);
        n = in.nextInt();
        m = in.nextInt();

        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= n; j++)
                if (i != j)w[i][j] = INF;
                else w[i][j] = 0;
        }
        for (int i = 1; i <= m; i++){
            int u, v, W;
            u = in.nextInt();
            v = in.nextInt();
            W = in.nextInt();
            w[u][v] = Math.min(w[u][v], W);
            w[v][u] = Math.min(w[v][u], W);
        }
        int s = in.nextInt();
        int e = in.nextInt();
//        dijkstra(n, s, e, w);
        spfa(n, s, e, w);
    }

    //1.首先初始化所有的边,记得判重边
    //2.选择一个初始点,对每个可达点进行松弛操作
    //3.每次选择点权值最大的点,再对可达点进行松弛操作
    //4.记得标记以选择的点
    public static void dijkstra(int n, int s, int e, int w[][]){
        int INF = 0x3f3f3f3f;
        boolean vis[] = new boolean[505];
        int node[] = new int[505];

        for (int i = 1; i <= n; i++)node[i] = (i==s)?0:INF;
        for (int i = 1; i <= n; i++){
            // x下一个最大的点编号,m下一个点最大的距离
            int x = 1, m = INF;
            for (int j = 1; j <= n; j++){
                if (!vis[j] && m >= node[j]){
                    m = node[j];
                    x = j;
                }
            }
            vis[x] = true;
            for (int j = 1; j <= n; j++)node[j] = Math.min(node[j], w[x][j]+node[x]);
        }
        System.out.println(node[e]);
    }

    //并查集
    public static int finds(int n, int f[]){
        return f[n] == n?n:(f[n] = finds(f[n], f));
    }

    //1.选择一个起点,将其丢入队列
    //2.每次取队首元素,对相邻点进行松弛操作,如果操作成功则入队列
    //3.直到队列为空。

    public static void spfa(int n, int s, int e, int w[][]){
        //
        int INF = 0x3f3f3f3f;
        Node d[] = new Node[500];
        for (int i = 1; i <= n; i++){
            d[i] = new Node((i==s)?0:INF, i);
        }
        Queue<Node> q = new LinkedList<Node>();
        q.offer(d[s]);
        while (!q.isEmpty()){
            Node t = q.poll();
            for (int i = 1; i <= n; i++){
                if (d[i].getVal() > d[t.getId()].getVal()+w[t.getId()][i]){
                    d[i].setVal(d[t.getId()].getVal()+w[t.getId()][i]);
                    q.offer(d[i]);
                }
            }
        }
        System.out.println(d[e].getVal());
    }

}
posted @ 2019-12-04 16:06  huas_lqy  阅读(156)  评论(0编辑  收藏  举报