资源限制
时间限制: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;
}
}
}
应该是主要参考了博主南墙加上自己的理解,有点忘记了