結果

問題 No.1602 With Animals into Institute 2
ユーザー Yu_212Yu_212
提出日時 2022-03-28 22:03:07
言語 Java21
(openjdk 21)
結果
AC  
実行時間 2,822 ms / 4,000 ms
コード長 10,714 bytes
コンパイル時間 3,589 ms
コンパイル使用メモリ 100,884 KB
実行使用メモリ 119,740 KB
最終ジャッジ日時 2024-11-07 12:44:32
合計ジャッジ時間 42,418 ms
ジャッジサーバーID
(参考情報)
judge2 / judge5
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 75 ms
38,332 KB
testcase_01 AC 77 ms
38,300 KB
testcase_02 AC 76 ms
38,168 KB
testcase_03 AC 232 ms
45,572 KB
testcase_04 AC 227 ms
45,248 KB
testcase_05 AC 280 ms
46,956 KB
testcase_06 AC 2,200 ms
111,168 KB
testcase_07 AC 2,067 ms
101,236 KB
testcase_08 AC 2,822 ms
119,740 KB
testcase_09 AC 2,429 ms
118,584 KB
testcase_10 AC 2,680 ms
114,756 KB
testcase_11 AC 2,624 ms
116,632 KB
testcase_12 AC 2,601 ms
115,588 KB
testcase_13 AC 2,730 ms
115,092 KB
testcase_14 AC 2,290 ms
118,224 KB
testcase_15 AC 2,164 ms
113,660 KB
testcase_16 AC 2,078 ms
103,212 KB
testcase_17 AC 2,258 ms
103,260 KB
testcase_18 AC 254 ms
47,528 KB
testcase_19 AC 258 ms
47,368 KB
testcase_20 AC 255 ms
46,792 KB
testcase_21 AC 252 ms
46,572 KB
testcase_22 AC 248 ms
46,904 KB
testcase_23 AC 246 ms
46,908 KB
testcase_24 AC 251 ms
47,020 KB
testcase_25 AC 244 ms
47,432 KB
testcase_26 AC 247 ms
47,284 KB
testcase_27 AC 75 ms
37,952 KB
testcase_28 AC 75 ms
38,584 KB
testcase_29 AC 75 ms
38,208 KB
testcase_30 AC 75 ms
38,264 KB
testcase_31 AC 76 ms
38,408 KB
testcase_32 AC 77 ms
38,400 KB
testcase_33 AC 77 ms
38,136 KB
testcase_34 AC 75 ms
38,444 KB
testcase_35 AC 76 ms
38,700 KB
testcase_36 AC 78 ms
38,612 KB
testcase_37 AC 77 ms
38,240 KB
testcase_38 AC 77 ms
38,408 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.IntUnaryOperator;
import java.util.function.LongUnaryOperator;
import java.util.stream.Collectors;

public class Main {
    static In in = new In();
    static Out out = new Out();
    static final long inf = 0x1fffffffffffffffL;
    static final int iinf = 0x3fffffff;
    static final double eps = 1e-9;
    static long mod = 1000000007;

    void solve() {
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        ShortestNonzeroPath.Group<Integer> group = new ShortestNonzeroPath.Group<>(0, (a, b) -> a ^ b);
        ShortestNonzeroPath<Integer> snp = new ShortestNonzeroPath<>(n, group);
        for (int i = 0; i < m; i++) {
            int a = in.nextInt() - 1;
            int b = in.nextInt() - 1;
            long c = in.nextLong();
            char[] x = in.nextCharArray();
            int label = 0;
            for (int j = 0; j < k; j++) {
                label |= (x[j] - '0') << j;
            }
            snp.addEdge(a, b, c, label);
            snp.addEdge(b, a, c, label);
        }
        snp.solve(n - 1);
        for (int i = 0; i < n - 1; i++) {
            out.println(snp.dist(i) == inf ? -1 : snp.dist(i));
        }
    }

    public static void main(String... args) {
        new Main().solve();
        out.flush();
    }
}

class ShortestNonzeroPath<T> {
    private final int n;
    private final List<List<Edge>> edges;
    private final Group<T> group;
    private final int[] uf;
    private final long[] nonzeroDist;

    public ShortestNonzeroPath(int n, Group<T> group) {
        this.n = n;
        this.edges = new ArrayList<>();
        this.group = group;
        this.uf = new int[n];
        this.nonzeroDist = new long[n];
        for (int i = 0; i < n; i++) {
            uf[i] = i;
            nonzeroDist[i] = Main.inf;
            edges.add(new ArrayList<>());
        }
    }

    public void addEdge(int u, int v, long len, T label) {
        edges.get(u).add(new Edge(u, v, len, label));
    }

    private int root(int x) {
        while (x != uf[x]) {
            x = uf[x] = uf[uf[x]];
        }
        return x;
    }

    public void solve(int s) {
        long[] dist = new long[n];
        int[] depth = new int[n];
        int[] parent = new int[n];
        List<T> label = new ArrayList<>(Collections.nCopies(n, group.identity));
        Arrays.fill(dist, Main.inf);
        Arrays.fill(depth, -1);
        Arrays.fill(parent, -1);
        PriorityQueue<Pair> queue = new PriorityQueue<>();
        dist[s] = 0;
        depth[s] = 0;
        queue.add(new Pair(null, 0));
        while (!queue.isEmpty()) {
            Pair pair = queue.remove();
            int u = pair.edge == null ? s : pair.edge.to;
            if (dist[u] < pair.len) {
                continue;
            }
            for (Edge edge : edges.get(u)) {
                int v = edge.to;
                if (dist[v] > dist[u] + edge.len) {
                    dist[v] = dist[u] + edge.len;
                    depth[v] = depth[u] + 1;
                    parent[v] = u;
                    label.set(v, group.operator.apply(label.get(u), edge.label));
                    queue.add(new Pair(edge, dist[edge.to]));
                }
            }
        }
        for (int u = 0; u < n; u++) {
            if (dist[u] == Main.inf) {
                continue;
            }
            for (Edge edge : edges.get(u)) {
                int v = edge.to;
                if (u < v && !Objects.equals(group.operator.apply(label.get(u), edge.label), label.get(v))) {
                    long len = dist[u] + dist[v] + edge.len;
                    queue.add(new Pair(edge, len));
                }
            }
        }
        while (!queue.isEmpty()) {
            Pair pair = queue.remove();
            int u = root(pair.edge.from);
            int v = root(pair.edge.to);
            List<Integer> bs = new ArrayList<>();
            while (u != v) {
                if (depth[u] > depth[v]) {
                    bs.add(u);
                    u = root(parent[u]);
                } else {
                    bs.add(v);
                    v = root(parent[v]);
                }
            }
            for (int x : bs) {
                uf[x] = u;
                nonzeroDist[x] = pair.len - dist[x];
                for (Edge edge : edges.get(x)) {
                    if (Objects.equals(group.operator.apply(label.get(x), edge.label), label.get(edge.to))) {
                        queue.add(new Pair(edge, nonzeroDist[x] + dist[edge.to] + edge.len));
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            if (!Objects.equals(label.get(i), group.identity) && dist[i] < nonzeroDist[i]) {
                nonzeroDist[i] = dist[i];
            }
        }
    }

    public long dist(int v) {
        return nonzeroDist[v];
    }

    private class Pair implements Comparable<Pair> {
        private final Edge edge;
        private final long len;

        private Pair(Edge edge, long len) {
            this.edge = edge;
            this.len = len;
        }

        @Override
        public int compareTo(Pair p) {
            return Long.compare(len, p.len);
        }
    }

    private class Edge {
        private final int from;
        private final int to;
        private final long len;
        private final T label;

        private Edge(int from, int to, long len, T label) {
            this.from = from;
            this.to = to;
            this.len = len;
            this.label = label;
        }
    }

    static class Group<T> {
        private final T identity;
        private final BinaryOperator<T> operator;

        public Group(T identity, BinaryOperator<T> operator) {
            this.identity = identity;
            this.operator = operator;
        }
    }
}

class In {
    private final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in), 0x10000);
    private StringTokenizer tokenizer;

    String next() {
        try {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                tokenizer = new StringTokenizer(reader.readLine());
            }
        } catch (IOException ignored) {
        }
        return tokenizer.nextToken();
    }

    int nextInt() {
        return Integer.parseInt(next());
    }

    long nextLong() {
        return Long.parseLong(next());
    }

    double nextDouble() {
        return Double.parseDouble(next());
    }

    char[] nextCharArray() {
        return next().toCharArray();
    }

    String[] nextStringArray(int n) {
        String[] s = new String[n];
        for (int i = 0; i < n; i++) {
            s[i] = next();
        }
        return s;
    }

    char[][] nextCharGrid(int n, int m) {
        char[][] a = new char[n][m];
        for (int i = 0; i < n; i++) {
            a[i] = next().toCharArray();
        }
        return a;
    }

    int[] nextIntArray(int n) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = nextInt();
        }
        return a;
    }

    int[] nextIntArray(int n, IntUnaryOperator op) {
        int[] a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = op.applyAsInt(nextInt());
        }
        return a;
    }

    int[][] nextIntMatrix(int h, int w) {
        int[][] a = new int[h][w];
        for (int i = 0; i < h; i++) {
            a[i] = nextIntArray(w);
        }
        return a;
    }

    long[] nextLongArray(int n) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++) {
            a[i] = nextLong();
        }
        return a;
    }

    long[] nextLongArray(int n, LongUnaryOperator op) {
        long[] a = new long[n];
        for (int i = 0; i < n; i++) {
            a[i] = op.applyAsLong(nextLong());
        }
        return a;
    }

    long[][] nextLongMatrix(int h, int w) {
        long[][] a = new long[h][w];
        for (int i = 0; i < h; i++) {
            a[i] = nextLongArray(w);
        }
        return a;
    }

    List<List<Integer>> nextEdges(int n, int m, boolean directed) {
        List<List<Integer>> res = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            res.add(new ArrayList<>());
        }
        for (int i = 0; i < m; i++) {
            int u = nextInt() - 1;
            int v = nextInt() - 1;
            res.get(u).add(v);
            if (!directed) {
                res.get(v).add(u);
            }
        }
        return res;
    }
}

class Out {
    private final PrintWriter out = new PrintWriter(System.out);
    boolean autoFlush = false;

    void println(Object... args) {
        if (args == null || args.getClass() != Object[].class) {
            args = new Object[] {args};
        }
        out.println(Arrays.stream(args).map(obj -> {
            Class<?> clazz = obj == null ? null : obj.getClass();
            return clazz == Double.class ? String.format("%.10f", obj) :
                   clazz == byte[].class ? Arrays.toString((byte[])obj) :
                   clazz == short[].class ? Arrays.toString((short[])obj) :
                   clazz == int[].class ? Arrays.toString((int[])obj) :
                   clazz == long[].class ? Arrays.toString((long[])obj) :
                   clazz == char[].class ? Arrays.toString((char[])obj) :
                   clazz == float[].class ? Arrays.toString((float[])obj) :
                   clazz == double[].class ? Arrays.toString((double[])obj) :
                   clazz == boolean[].class ? Arrays.toString((boolean[])obj) :
                   obj instanceof Object[] ? Arrays.deepToString((Object[])obj) :
                   String.valueOf(obj);
        }).collect(Collectors.joining(" ")));
        if (autoFlush) {
            out.flush();
        }
    }

    void println(char[] s) {
        out.println(String.valueOf(s));
        if (autoFlush) {
            out.flush();
        }
    }

    void println(int[] a) {
        StringJoiner joiner = new StringJoiner(" ");
        for (int i : a) {
            joiner.add(Integer.toString(i));
        }
        out.println(joiner);
        if (autoFlush) {
            out.flush();
        }
    }

    void println(long[] a) {
        StringJoiner joiner = new StringJoiner(" ");
        for (long i : a) {
            joiner.add(Long.toString(i));
        }
        out.println(joiner);
        if (autoFlush) {
            out.flush();
        }
    }

    void flush() {
        out.flush();
    }
}
0