Acwing 4074. 铁路与公路 java 弗洛伊德 脑经急转弯

🤠 原题地址

👨‍🏫 两车不能同时到达除 1 和 n 的城市,虚晃一枪,故意误导的,输入铁路,没铁路才有公路,并不会冲突,并且 1 ~ n 必有一条直达路 (公 / 铁),O(1)解决一台车的最短路问题

👨‍🏫 弗洛伊德

① 核心:以每个点为 中间人 试图去 拉近它的 两邻居的距离
② 遍历每一个点,遍历每一个入度,遍历每一个出度

🐷 O( n^3 )

import java.io.*;
import java.util.*;

public class Main
{
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

	static int N = 410, n, m;
	static int[][] g = new int[N][N];
	static int[][] f = new int[N][N];// 铁路邻接矩阵
	static int[][] d = new int[N][N];

	public static void main(String[] args) throws IOException
	{
		String[] split = in.readLine().split(" ");
		n = Integer.parseInt(split[0]);
		m = Integer.parseInt(split[1]);

//		初始化邻接矩阵
		for (int i = 0; i < f.length; i++)
			Arrays.fill(f[i], 0x3f3f3f3f);
		for (int i = 0; i < g.length; i++)
			Arrays.fill(g[i], 0x3f3f3f3f);

//		输入铁路
		for (int i = 0; i < m; i++)
		{
			String[] split2 = in.readLine().split(" ");
			int a = Integer.parseInt(split2[0]);
			int b = Integer.parseInt(split2[1]);

			f[a][b] = f[b][a] = 1;
		}

//		自行补充公路
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (f[i][j] != 1 && i != j)
					g[i][j] = 1;

		int res = Math.max(floyd(f), floyd(g));

		if (res == 0x3f3f3f3f)
			res = -1;

		out.write(res + "");
		out.flush();
	}

	private static int floyd(int[][] d)
	{

		for (int k = 1; k <= n; k++)
			for (int i = 1; i <= n; i++)
				for (int j = 1; j <= n; j++)
					d[i][j] = Math.min(d[i][j], d[i][k] + d[k][j]);

		return d[1][n];
	}
}

👨‍🏫 dijkstra O( n^2 )

import java.io.*;
import java.util.*;

public class Main
{
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));

	static int N = 410, n, m;
	static int[][] g = new int[N][N];
	static int[][] f = new int[N][N];// 铁路邻接矩阵
	static int[] dist = new int[N];
	static boolean[] st = new boolean[N];

	public static void main(String[] args) throws IOException
	{
		String[] split = in.readLine().split(" ");
		n = Integer.parseInt(split[0]);
		m = Integer.parseInt(split[1]);

//		初始化邻接矩阵
		for (int i = 0; i < f.length; i++)
			Arrays.fill(f[i], 0x3f3f3f3f);
		for (int i = 0; i < g.length; i++)
			Arrays.fill(g[i], 0x3f3f3f3f);

//		输入铁路
		for (int i = 0; i < m; i++)
		{
			String[] split2 = in.readLine().split(" ");
			int a = Integer.parseInt(split2[0]);
			int b = Integer.parseInt(split2[1]);

			f[a][b] = f[b][a] = 1;
		}

//		自行补充公路
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				if (f[i][j] != 1 && i != j)
					g[i][j] = 1;

		int a = dijkstra(f);
		int b = dijkstra(g);

		if (a == -1 || b == -1)
			System.out.println(-1);
		else
			System.out.println(Math.max(a, b));

	}

	private static int dijkstra(int[][] a)
	{
		if (a[1][n] == 1)
			return 1;

//		重复使用的记得要初始化
		Arrays.fill(dist, 0x3f3f3f3f);
		Arrays.fill(st, false);

		dist[1] = 0;
		for (int i = 0; i < n - 1; i++)
		{
			int t = -1;
//			求出到当前已知最短路的 集合 距离最近 的节点
			for (int j = 1; j <= n; j++)
				if (!st[j] && (t == -1 || dist[j] < dist[t]))
					t = j;

			st[t] = true;
			for (int j = 1; j <= n; j++)
				dist[j] = Math.min(dist[j], dist[t] + a[t][j]);
		}
		if (dist[n] == 0x3f3f3f3f)
			return -1;
		else
			return dist[n];

	}
}

posted @ 2023-03-08 00:00  兑生  阅读(11)  评论(0编辑  收藏  举报  来源
Live2D