算法训练 最短路

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内存才能继续运行

即使不爆堆,也不能满足题目资源限制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值