1. 程式人生 > >圖論演算法(一)--最短路徑的DFS/BFS解法(JAVA )

圖論演算法(一)--最短路徑的DFS/BFS解法(JAVA )

最短路徑–城市路徑問題:

問題描述:求從1號城市到5號城市的最短路徑長度
city
Input:
5 8
1 2 2
1 5 10
2 3 3
2 5 7
3 1 4
3 4 4
4 5 5
5 3 3
Output:
9

DFS

import java.util.Scanner;
public class minPath {
    static int min = 99999999;
    static int[][] e = new int[100][100];
    static int[] book = new int[100];
    static
int n, m; static Scanner input = new Scanner(System.in); public static void main(String[] args) { n = input.nextInt(); m = input.nextInt(); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { if (i == j) { e[i][j] = 0
; } else { e[i][j] = 99999999; } } } for (int i = 1; i <= m; i++) { int a = input.nextInt(); int b = input.nextInt(); int c = input.nextInt(); e[a][b] = c; } book[1
] = 1; dfs(1, 0); System.out.println(min); } public static void dfs(int cur, int dis) { /** * 如果當前路徑大於之前找到的最小值,可直接返回 * */ if (dis > min) { return; } /** * 判斷是否達到最後一個結點,更新最小值,返回 * */ if(cur == n) { if (dis < min) { min = dis; return; } } /** * 當前點到其他各點之間可連通但是還未新增進來時,遍歷執行 * */ for (int i = 1; i <= n; i++) { if (e[cur][i] != 99999999 && book[i] == 0) { book[i] = 1; dfs(i, dis+e[cur][i]); /** * 回溯 **/ book[i] = 0; } } return; } }

最短路徑–轉乘問題:

問題描述:求從1號城市到5號城市的最短路徑長度
Input:
5 7 1 5
1 2
1 3
2 3
2 4
3 4
3 5
4 5
Output:
2
path2
這個題目與上一個的區別就在於,這些路徑是沒有權值的,也就是說只需要找出到達一個點的最短距離就可以了,記錄次數即可。

BFS

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

class node {
    int x;
    int s;
    node(int x, int s) {
        this.x = x;
        this.s = s;
    }
}

public class minPath {
    static int[][] e = new int[51][51];
    static int[] book = new int[51];
    static int n, m;
    static int start, end;
    static int mark, sum;
    static Queue<node> queue = new LinkedList<>();
    static Scanner input = new Scanner(System.in);
    public static void main(String[] args) {
        n = input.nextInt();
        m = input.nextInt();
        start = input.nextInt();
        end = input.nextInt();
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                if (i == j) {
                    e[i][j] = 0;
                } else {
                    e[i][j] = 99999999;
                }
            }
        }
        for (int i = 1; i <= m; i++) {
            int a = input.nextInt();
            int b = input.nextInt();
            e[a][b] = 1;
            e[b][a] = 1;
        }

        queue.offer(new node(start, 0));
        book[1] = start;

        bfs();
        System.out.println(sum);
    }
    public static void bfs() {
        int flag = 0;
        while (!queue.isEmpty()) {
            int cur = queue.peek().x;
            for (int i = 1; i <= n; i++) {
                if(e[cur][i] != 99999999 && book[i] == 0) {
                    mark = i;
                    sum = queue.peek().s + 1;
                    queue.offer(new node(i, sum));
                    book[i] = 1;
                }
                if(mark == end) {
                    flag = 1;
                    break;
                }
            }
            if(flag == 1) {
                break;
            }
            queue.remove();
        }
        return;
    }
}

基本上能用深度優先的問題都可以用廣度優先,但是廣度優先更適合無向圖,或者說所有邊的權值一樣的情況,大家可以通過多做題靈活使用這兩種方法