欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java有向无权图的单源点最短路径-邻接矩阵和邻接表

程序员文章站 2023-12-25 18:31:03
...

引入

此文章是随手笔记,写的不好见谅。

  1. 无权图的单源点最短路径我这用BFS实现
  2. 主要的就是图的实现与BFS的搜索,其它没什么
  3. 为了下一步的有向有权图单源点最短路径做基础

代码

1.用邻接矩阵表示图的

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

public class MatrixShortestPath {
	static int n;// 点数
	static int e;// 边数
	static int G[][];// 领接矩阵
	static int dis[];// 路径 dis[i] = j, 默认1到节点i最短路径j
	static int path[];// 记录路线
	
	// BFS最短路径
	public static void Bfs(int u){
		path[u] = -1;// 起点
		// 源点 初始化为访问过
		dis[u] = 0;
		Queue<Integer> qu = new LinkedList<Integer>();// 队列
		qu.offer(u);// 添加源点进入
		while(!qu.isEmpty()){
			u = qu.poll();// 弹出最早的
			// 以u点扩散
			for(int i = 1; i <= n; i++){
				/*
				dis[i] == -1:代表是否访问过
				因为无权图,边权值默认为1,不用判断出现的节点k使,节点i到节点j的长度 > 节点i到节点k + 节点k到节点j的长度
				G[u][i] == 1,点u到点i存在路径
				*/
				if(dis[i] == -1 && G[u][i] == 1){
					// 更新路径:为源点到点u的路径+1,因为无权图,只需+1
					dis[i] = dis[u] + 1;
					// 记录路径
					path[i] = u;
					// 添加到队列中
					qu.offer(i);
				}
			}
		}
	}
	// 打印路径
	public static void printPath(int u){
		// 如果是-1代表到达起点
		if(path[u] == -1){
			System.out.print("路径:"+u+"->");
		}else{
			// 上一层
			printPath(path[u]);
			// 递归结束,打印路径
			System.out.print(u+"->");
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();// 点数
		e = sc.nextInt();// 边数
		// 初始化
		G = new int[n + 1][n + 1];
		dis = new int[n + 1];
		path = new int[n + 1];
		// 路径长度初始化为-1,不仅可以代表源点到点i路径长度,还可以代表是否访问过
		for(int i = 0; i < dis.length; i++){
			dis[i] = -1;
		}
		// 输入边
		int u, v;
		for(int i = 0; i < e; i++){
			u = sc.nextInt();
			v = sc.nextInt();
			G[u][v] = 1; // 有向图
		}
		// 从源点1开始的路径
		Bfs(1);
		// 得到长度
		for(int i = 1; i <= n; i++){
			System.out.print("源点1到点"+i+"的长度:"+dis[i]+",");
			// 打印路径
			printPath(i);
			System.out.println();
		}
		sc.close();
	}
}

2.输入的数据
6 8
1 2
1 3
2 6
3 4
3 5
3 6
4 5
4 6
3.对应的无权图
Java有向无权图的单源点最短路径-邻接矩阵和邻接表

4.输出
Java有向无权图的单源点最短路径-邻接矩阵和邻接表
5.对应的邻接表表现图

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

public class AdlistShoterPath {
	static int n;// 点数
	static int e;// 边数
	static ArrayList<Integer> G[];// 邻接表
	static int dis[];// 路径 dis[i] = j, 默认1到节点i最短路径j
	static int path[];// 记录路线
	
	// BFS最短路径
	public static void Bfs(int u){
		path[u] = -1;// 起点
		// 源点 初始化为访问过
		dis[u] = 0;
		Queue<Integer> qu = new LinkedList<Integer>();
		qu.offer(u);// 添加源点进入
		while(!qu.isEmpty()){
			u = qu.poll();
			// 以u点扩散,得到它的邻接表
			for(int i = 0; i < G[u].size(); i++){
				// 只需判断是否访问过即可
				if(dis[G[u].get(i)] == -1){
					// 更新路径
					dis[G[u].get(i)] = dis[u] + 1;
					// 记录路径
					path[G[u].get(i)] = u;
					qu.offer(G[u].get(i));
				}
			}
		}
	}
	// 打印路径
	public static void printPath(int u){
		// 如果是0代表到达起点
		if(path[u] == -1){
			System.out.print("路径:"+u+"->");
		}else{
			// 上一层
			printPath(path[u]);
			// 递归结束,打印路径
			System.out.print(u+"->");
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		e = sc.nextInt();
		// 初始化
		G =  new ArrayList[n + 1];
		dis = new int[n + 1];
		path = new int[n + 1];
		for(int i = 0; i < G.length; i++){
			G[i] = new ArrayList<>();
		}
		// 路径初始化为-1
		for(int i = 0; i < dis.length; i++){
			dis[i] = -1;
		}
		// 输入边
		int u, v;
		for(int j = 0; j < e; j++){
			u = sc.nextInt();
			v = sc.nextInt();
			G[u].add(v);// 有向图的添加
		}
		// 从1开始的路径
		Bfs(1);
		// 得到长度
		for(int i = 1; i <= n; i++){
			System.out.print("源点1到点"+i+"的长度:"+dis[i]+",");
			// 打印路径
			printPath(i);
			System.out.println();
		}
		sc.close();
	}
}

上一篇:

下一篇: