蓝桥杯最短路java

资源限制

时间限制:1.0s   内存限制:256.0MB

问题描述

给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

输入格式

第一行两个整数n, m。

接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

输出格式

共n-1行,第i行表示1号点到i+1号点的最短路。

样例输入

3 3
1 2 -1
2 3 -1
3 1 2

样例输出

-1
-2

数据规模与约定

对于10%的数据,n = 2,m = 2。

对于30%的数据,n <= 5,m <= 10。

对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;

public class 最短路 {
public static void main(String[] args) throws IOException {
		StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		in.nextToken();
		int n = (int) in.nval;
		in.nextToken();
		int m = (int) in.nval;
		// 定义邻接表内部是node,初始化
		@SuppressWarnings("unchecked")
		List<node>[] list = new ArrayList[n];
		for (int i = 0; i < n; i++) {
			list[i] = new ArrayList<>();
		}
		// 存储结果,用一个boolean类型用于判断该节点是否在队内
		boolean[] flag = new boolean[n];
		int[] dist = new int[n];
		// 除了0节点,其余先视其为最大
		for (int i = 1; i < n; i++) {
			dist[i] = Integer.MAX_VALUE;
		}
		// 添加边之间的距离数据
		for (int i = 0; i < m; i++) {
			in.nextToken();
			int u = (int) in.nval;
			in.nextToken();
			int v = (int) in.nval;
			in.nextToken();
			int l = (int) in.nval;
			// 下标减1
			list[u - 1].add(new node(v - 1, l));
		}
		// 1先入队,下标0
		Queue<Integer> q = new ArrayDeque<Integer>();
		q.add(0);
		// 判断到队列为空,即所有的节点周围的长度都不会变化了
		while (!q.isEmpty()) {
			// 队首出队
			// 因为从0开始遍历,所以能够确定下一个x的值就是目前到0节点的最短距离,并且肯定能遍历到所有距离
			// 这样dist[x] + length就是现在x下的子节点的dist[index],判断大小
			int x = q.poll();
			flag[x] = false;
			// 遍历出x下x与所有连接的节点的直接距离以及其编号,那么以x为节点
			for (int i = 0; i < list[x].size(); i++) {

				int index = list[x].get(i).a;
				int length = list[x].get(i).b;
// 判断该节点距离0更短,还是目前节点(x)加上该节点到目前节点的距离更短,是则更新
				if (dist[index] > dist[x] + length) {
					dist[index] = dist[x] + length;
					// 队中没有该点则入队
					if (!flag[index]) {
						q.add(index);
						flag[index] = true;
					}
				}
			}

		}
		// 遍历输出dist
		for (int i = 1; i < n; i++) {
			out.println(dist[i]);
		}
		out.flush();
	}

//创建结构,方便把所有同节点的数据存储在同一个节点下
	static class node {
		// a,b表示v跟l
		int a, b;

		public node(int a, int b) {
			this.a = a;
			this.b = b;
		}
	}
}

应该是主要参考了博主南墙加上自己的理解,有点忘记了

链接

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

皮玄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值