Dijkstra and BFS find the shortest path in weighted and unweighted graphs [Java]

1. Dijkstra’s algorithm solves the shortest path problem of weighted graphs

1. pre

	迪杰斯特拉算法采用贪心的策略,集合T{}用来存放当前已找到的最短路径节点集合。将起始点的路径权重赋
为0,当前节点不能到达的节点权重赋为无穷大。

2. Algorithm Demonstration

Shown below is an undirected weighted graph to find the shortest path:
2.1

Specific steps:
Add the node with the minimum path value to the T set each time.
2.2
Comprehensive understanding with the graph:
2.3
Adjacency list structure: The head node of the linked list stores the subscript.
2.4

3. Java code

题目:一共有n个点,m条无向边,每条边都有长度d和花费p,给定起点s终点t,要求输出起点到终点的最短距离
及其花费,如果最短距离有多条路线,则输出花费最少的。
输出:最小距离和花费。

创建Vertex类,构建邻接表:

class Edge {
    
    
	// 存放边的信息,next表示下一个节点,dist表示长度,cost表示花费
    int next;
    int dist;
    int cost;
    public Edge(int next, int dist, int cost) {
    
    
        this.next = next;
        this.dist = dist;
        this.cost = cost;
    }
}

class Vertex {
    
    
    int num;
    ArrayList<Edge> edge;  // 使用链表结构存储
    public Vertex(int num) {
    
    
        this.num = num;
        this.edge = new ArrayList<Edge>();
    }
}

ACM mode:

Scanner in = new Scanner(System.in);
while (in.hasNext()) {
    
    
	int n = in.nextInt(); // 点数
    int m = in.nextInt(); // 边数
    if (m == 0) break;
    Vertex[] list = new Vertex[n + 1];
    // 初始化Vertex
    for (int i = 1; i <= n; i++){
    
    
    	list[i] = new Vertex(i);
    }
    for (int i = 0; i < m; i++) {
    
    
        int a = in.nextInt();
        int b = in.nextInt();
        int dist = in.nextInt();  // 长度
        int cost = in.nextInt();  // 花费
        list[a].edge.add(new Edge(b, dist, cost));  // a->b 的长度和花费
        list[b].edge.add(new Edge(a, dist, cost));  
    }
    int s = in.nextInt(); // 起点
    int t = in.nextInt(); // 终点
    boolean[] marked = new boolean[n + 1];  // 用来记录当前节点是否更新
    int[] cost = new int[n + 1];
    int[] dist = new int[n + 1];
    for (int i = 1; i <= n; i++) {
    
    
        cost[i] = Integer.MAX_VALUE;  // 初始花费设为max
        dist[i] = -1;  // 不可达用-1表示
        marked[i] = false;
    }
    dist[s] = 0;
    cost[s] = 0;
    marked[s] = true;
    int p = s;  // 当前起点p
    // Dijkstra
    for(int i=1;i<=n;i++){
    
    
      for(int j=0;j<list[p].edge.size();j++){
    
    
          int next = list[p].edge.get(j).next;
          int c = list[p].edge.get(j).cost;
          int d = list[p].edge.get(j).dist;
          if(marked[next]==true) continue;
          // 三种情况进行更新:距离未更新时、距离需更新时、距离相等花费变小时
          if(dist[next]==-1 || dist[next]>dist[p]+d || dist[next]== dist[p]+d && cost[next]>cost[p]+c){
    
    
              dist[next] = dist[p] + d;
              cost[next] = cost[p] + c;
          }
      }
      int min = Integer.MAX_VALUE;
      for(int j=1;j<=n;j++){
    
    
          if(marked[j]==true) continue;
          if(dist[j]==-1) continue;
          if(dist[j]<min){
    
    
              min = dist[j];
              p = j;
          }
      }
      marked[p] = true;
  }
  System.out.printf("%d %d\n", dist[t],cost[t]);

2. BFS algorithm solves the shortest path problem of unweighted graphs

1. pre

Breadth-first search algorithm (BFS) is a search algorithm implemented using queue.

Depth-first search algorithm (DFS) is a search algorithm implemented using recursion.

2. Algorithm

题目:给定n个节点,节点从0依次编号,0固定为根节点,若节点设置障碍则不可达,输出从根节点到叶子结点的
路径(只有一条边相连的为叶子结点),否则输出NULL。
输入:
	第一行 n 【节点数】
	第二行 m 【边数】
	接下来m行 x y 【x与y相连】
	第m+3行 b 【接下来有b个障碍物节点】
	接下来b行 k 【节点k有障碍物】 
例:
	7
	6
	0 1
	0 3
	1 2
	3 4
	1 5
	5 6
	1
	4

Because the adjacency list structure is used to store adjacent nodes, it is not required to be a binary tree. It is drawn in the shape of a tree for convenience.

2.1
same创建Vertex类,构建邻接表:

class Edge {
    
    
    int next;
    public Edge(int next) {
    
    
        this.next = next;
    }
}
class Vertex {
    
    
    int num;
    ArrayList<Edge> edge;
    public Vertex(int num) {
    
    
        this.num = num;
        this.edge = new ArrayList<Edge>();
    }
}

bfs

public static int bfs(int x, Vertex[] list, int[] book, int[] child){
    
    
   Queue<Integer> queue = new LinkedList<>();
   queue.offer(x);
   while (!queue.isEmpty()){
    
    
       int top = queue.poll();
       int size = list[top].edge.size();  // 相连的边的个数
       if (size == 0){
    
    
           return top;
       }else{
    
    
           for (int i = 0; i < size; i++) {
    
    
               int next = list[top].edge.get(i).next;
               if (book[next] == 1) continue;
               queue.offer(next);
               child[next] = top;
           }
       }
   }
   return -1;
}
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
    
    
    int n = scan.nextInt();
    int m = scan.nextInt();
    int[] child = new int[n];  
    Arrays.fill(child, -1);
    Vertex[] list = new Vertex[n];
    for (int i = 0; i < n; i++)
        list[i] = new Vertex(i);
    for (int i = 0; i < m; i++) {
    
    
        int a = scan.nextInt();
        int b = scan.nextInt();
        list[a].edge.add(new Edge(b));  // 单向
    }
    int block_num = scan.nextInt();
    int[] book = new int[n];
    for (int i = 0; i < block_num; i++) {
    
    
        int z = scan.nextInt();
        book[z] = 1;
    }
    int ans = bfs(0, list, book, child);
    if (ans == -1) {
    
    
        System.out.println("NULL");
    } else {
    
    
        Deque<Integer> res = new LinkedList<>();
        while (ans != -1) {
    
    
            res.addFirst(ans);
            ans = child[ans];
        }
        while (!res.isEmpty()) {
    
    
            System.out.print(res.poll() + " ");
        }
    }
}

example:
2

Guess you like

Origin blog.csdn.net/weixin_55488173/article/details/130289690