Submission #3607623


Source Code Expand

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

public class Main {

    static int N, M, S, T;
    static Edge[] E;

    public static void main(String[] args) {
        FastScanner sc = new FastScanner(System.in);
        N = sc.nextInt();
        M = sc.nextInt();
        S = sc.nextInt()-1;
        T = sc.nextInt()-1;
        E = new Edge[M];
        for (int i = 0; i < M; i++) {
            E[i] = new Edge(sc.nextInt()-1, sc.nextInt()-1, sc.nextInt());
        }

        System.out.println(solve());
    }

    static class Edge {
        final int a, b, d;

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

        int opposite(int x) {
            return a == x ? b : a;
        }
    }

    static class State implements Comparable<State> {
        int a;
        int d;

        public State(int a, int d) {
            this.a = a;
            this.d = d;
        }

        @Override
        public int compareTo(State o) {
            return Integer.compare(d, o.d);
        }
    }

    static int MOD = 1_000_000_007;
    static long INF = Long.MAX_VALUE / 2;

    static long solve() {
        Edge[][] G = adjB(N, E);

        Result r = calc(G);
        int collision = countCollision(G, r.dist);
        // System.out.println("dist=" + r.dist + " time=" + r.time + " collision=" + collision);
        return ((long)r.time * r.time - collision + MOD) % MOD;
    }

    static class Result {
        long dist;
        int time;

        public Result(long dist, int time) {
            this.dist = dist;
            this.time = time;
        }
    }

    static Result calc(Edge[][] G) {
        long[] dist = new long[N];
        int[] time = new int[N];
        Arrays.fill(dist, INF);
        Arrays.fill(time, -1);

        PriorityQueue<State> q = new PriorityQueue<>();
        q.add(new State(S, 0));
        dist[S] = 0;
        time[S] = 1;

        while( !q.isEmpty() ) {
            State s = q.poll();
            if( dist[s.a] != s.d ) continue;

            for (Edge e : G[s.a]) {
                int next = e.opposite(s.a);
                int nd = s.d + e.d;
                if( dist[next] > nd ) {
                    dist[next] = nd;
                    time[next] = time[s.a];
                    q.add( new State(next, nd) );

                } else if( dist[next] == nd ) {
                    time[next] += time[s.a];
                    time[next] %= MOD;
                }
            }
        }
        return new Result(dist[T], time[T]);
    }

    static int countCollision(Edge[][] G, long st) {
        long[] dist = new long[N];
        int[] time = new int[N];
        int[] collision = new int[N];
        Arrays.fill(dist, INF);
        Arrays.fill(time, -1);

        PriorityQueue<State> q = new PriorityQueue<>();
        q.add(new State(S, 0));
        dist[S] = 0;
        time[S] = 1;
        collision[S] = 0;

        while( !q.isEmpty() ) {
            State s = q.poll();
            if( dist[s.a] != s.d ) continue;

            for (Edge e : G[s.a]) {
                int next = e.opposite(s.a);
                int nd = s.d + e.d;

                if( dist[next] > nd ) {
                    dist[next] = nd;
                    time[next] = time[s.a];
                    if( isCollision(dist[s.a], e, st) ) {
                        collision[next] = time[s.a];
                    } else {
                        collision[next] = collision[s.a];
                    }

                    q.add( new State(next, nd) );

                } else if( dist[next] == nd ) {
                    time[next] += time[s.a];
                    time[next] %= MOD;
                    if( isCollision(dist[s.a], e, st) ) {
                        collision[next] += (collision[s.a] + time[s.a]);
                        collision[next] %= MOD;
                    } else {
                        collision[next] += collision[s.a];
                        collision[next] %= MOD;
                    }
                }
            }
        }
        return collision[T];
    }

    // (dist[n.a], dist[n.a] + e.d]の間にcollisionするかどうか
    static boolean isCollision(long dist, Edge e, long st) {
        long a = dist;
        long b = dist + e.d;
        long d = (st - dist);
        long c = d - e.d;

        // (a, b] と [c, d) を 比較するの辛いのでb, cを比較してしまう
        if( b == c ) return true;

        // (a, b) (c, d)が重複するかどうか
        if( a < c ) {
            return c < b;
        } else {
            return a < d;
        }
    }

    static Edge[][] adjB(int n, Edge[] E) {
        Edge[][] adj = new Edge[n][];
        int[] cnt = new int[n];
        for (Edge e : E) {
            cnt[e.a]++;
            cnt[e.b]++;
        }
        for (int i = 0; i < n; i++) {
            adj[i] = new Edge[cnt[i]];
        }
        for (Edge e : E) {
            adj[e.a][--cnt[e.a]] = e;
            adj[e.b][--cnt[e.b]] = e;
        }
        return adj;
    }

    @SuppressWarnings("unused")
    static class FastScanner {
        private BufferedReader reader;
        private StringTokenizer tokenizer;

        FastScanner(InputStream in) {
            reader = new BufferedReader(new InputStreamReader(in));
            tokenizer = null;
        }

        String next() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }

        String nextLine() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    return reader.readLine();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken("\n");
        }

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

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

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

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

Submission Info

Submission Time
Task E - Avoiding Collision
User kusomushi
Language Java8 (OpenJDK 1.8.0)
Score 0
Code Size 6939 Byte
Status WA
Exec Time 760 ms
Memory 69756 KB

Judge Result

Set Name Sample All
Score / Max Score 0 / 0 0 / 700
Status
AC × 4
AC × 8
WA × 14
Set Name Test Cases
Sample sample01.txt, sample02.txt, sample03.txt, sample04.txt
All 01.txt, 02.txt, 03.txt, 04.txt, 05.txt, 06.txt, 07.txt, 08.txt, 09.txt, 10.txt, 11.txt, 12.txt, 13.txt, 14.txt, 15.txt, 16.txt, 17.txt, 18.txt, sample01.txt, sample02.txt, sample03.txt, sample04.txt
Case Name Status Exec Time Memory
01.txt AC 578 ms 64108 KB
02.txt AC 540 ms 64060 KB
03.txt WA 760 ms 64148 KB
04.txt WA 568 ms 61920 KB
05.txt WA 547 ms 68056 KB
06.txt WA 559 ms 69756 KB
07.txt WA 520 ms 63400 KB
08.txt WA 394 ms 43708 KB
09.txt WA 574 ms 63372 KB
10.txt WA 643 ms 64564 KB
11.txt AC 691 ms 63068 KB
12.txt AC 608 ms 61196 KB
13.txt WA 515 ms 64368 KB
14.txt WA 509 ms 62376 KB
15.txt WA 533 ms 62980 KB
16.txt WA 526 ms 65600 KB
17.txt WA 555 ms 64680 KB
18.txt WA 550 ms 63508 KB
sample01.txt AC 75 ms 19412 KB
sample02.txt AC 75 ms 21204 KB
sample03.txt AC 75 ms 19156 KB
sample04.txt AC 73 ms 21332 KB