ALGO-5 最短路
资源限制
时间限制: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,保证从任意顶点都能到达其他所有顶点。
BFS :
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
InputReader in = new InputReader(System.in);
PrintWriter out = new PrintWriter(System.out);
int n = in.nextInt(), m = in.nextInt();
int[] weight = new int[n + 1];
Graph<Edge> graph = new Graph(n);
boolean[] marked = new boolean[n + 1];
Arrays.fill(weight, 2, weight.length, Integer.MAX_VALUE);
while (m-- > 0) graph.add(in.nextInt(), new Edge(in.nextInt(), in.nextInt()));
Queue<Integer> queue = new LinkedList<Integer>();
for (Edge e: graph.adj(1)) {
weight[e.E] = e.weight;
queue.add(e.E);
}
marked[1] = true;
while (queue.size() > 0) {
int V = queue.remove(), temp;
for (Edge e: graph.adj(V))
if (weight[e.E] > (temp = e.weight + weight[V])) {
if (!marked[e.E]) marked[e.E] = queue.add(e.E);
weight[e.E] = temp;
}
marked[V] = false;
}
for (int i = 2; i <= n; i++) out.println(weight[i]);
out.close();
in.close();
}
static class Edge {
int E;
int weight;
Edge(int E, int weight) {
this.E = E;
this.weight = weight;
}
}
static class Graph<T> {
List[] adj;
Graph(int size) {
adj = new List[size + 1];
for (int i = 1; i <= size; i++) adj[i] = new ArrayList<T>();
}
void add(int V, T E) { adj[V].add(E); }
List<T> adj(int V) { return adj[V]; }
}
static class InputReader {
BufferedReader read;
StringTokenizer tokens;
String delimiters;
InputReader (InputStream in, String delimiters) {
this.read = new BufferedReader(new InputStreamReader(in));
this.delimiters = delimiters;
this.tokens = new StringTokenizer("", delimiters);
}
InputReader (InputStream in) { this(in, " \t\n\r\f"); }
String next() throws IOException {
while (!tokens.hasMoreTokens()) tokens = new StringTokenizer(read.readLine(), delimiters);
return tokens.nextToken();
}
int nextInt() throws IOException { return Integer.parseInt(next()); }
void close() throws IOException { read.close(); }
}
}
虽然调试了较长时间,但这是我第一道没有参考其他博文实现的图问题,
上一次解图问题还是19年底,家真的是个有魔力的地方
对于内存和时间的消耗我个人还是很满意的
有人能告诉我这个编译信息有什么影响或者问题出在哪吗,写啥啥出这个
Floyd:
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
InputReader in = new InputReader(System.in);
PrintWriter out = new PrintWriter(System.out);
int n = in.nextInt() + 1, m = in.nextInt(), V = 1;
int[][] map = new int[n][n];
for (int i = 1; i < n; i++) Arrays.fill(map[i], 1, n, Integer.MAX_VALUE);
while (m-- > 0) map[in.nextInt()][in.nextInt()] = in.nextInt();
for (int k = V + 1, temp; k < n; k++)
for (int i = 1; i < n; i++) {
if (map[i][k] == Integer.MAX_VALUE) continue;
for (int j = 1; j < n; j++) {
if (map[k][j] == Integer.MAX_VALUE) continue;
if (map[i][j] > (temp = map[i][k] + map[k][j])) map[i][j] = temp;
}
}
for (int i = V + 1; i < n; i++) out.println(map[1][i]);
out.close();
in.close();
}
static class InputReader { ... }
}
序号 6.、10. n的大小为20000,9.则为10000
也就是说至少在 map[][] 上分配 320MB内存才能继续运行
即使不爆堆,也不能满足题目资源限制