《最短路径树》

https://www.luogu.com.cn/problem/P2505

卡卡常数了,看测评机了。

import java.io.*;
import java.util.*;


public class Main {
    public static int N = 1505;
    public static int M = 5005;
    static int Mod = 1000000007;
    static StreamTokenizer cin = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));

    static class Edge{
        int to,dis,tag,id;
        Edge(int x,int y,int z,int d) {
            to = x;
            dis = y;
            tag = z;
            id = d;
        }
    }
    static class Pair {
        int u,d;
        Pair(int x,int y) {
            u = x;
            d = y;
        }
    }
    static List<Edge> edges[] = new List[N];
    static int dis[] = new int[N];
    static int ans[] = new int[M];
    static long cnt[] = new long[N];
    static long cnt2[] = new long[N];
    static int in[] = new int[N];
    static PriorityQueue<Pair> Q = new PriorityQueue<>(new Comparator<Pair>() {
        @Override
        public int compare(Pair o1, Pair o2) {
            return o1.d - o2.d;
        }
    });

    static void init(int up) {
        for(int i = 1;i <= up;++i) edges[i] = new ArrayList<>();
    }
    static void dijkstra(int s,int n) {
        for(int i = 1;i <= n;++i) dis[i] = Integer.MAX_VALUE;
        dis[s] = 0;
        Q.add(new Pair(s,0));
        while (!Q.isEmpty()) {
            Pair q = Q.poll();
            if(q.d < dis[q.u]) continue;;
            for(Edge e : edges[q.u]) {
                if(dis[e.to] > dis[q.u] + e.dis) {
                    dis[e.to] = dis[q.u] + e.dis;
                    Q.add(new Pair(e.to,dis[e.to]));
                }
            }
        }
        cal(s,n);
    }
    static void cal(int s,int n) {
        for(int i = 1;i <= n;++i) {
            in[i] = 0;
            for(int j = 0;j < edges[i].size();++j) {
                edges[i].get(j).tag = 0;
            }
        }
        for(int i = 1;i <= n;++i) {
            for(int j = 0;j < edges[i].size();++j) {
                int v = edges[i].get(j).to;
                int d = edges[i].get(j).dis;
                if(dis[v] == dis[i] + d) {
                    edges[i].get(j).tag = 1;
                    in[v]++;
                }
            }
        }
        topo(s,n,in);
    }
    static void topo(int s,int n,int in[]) {
        Queue<Integer> Queue = new LinkedList<>();
        Stack<Integer> S = new Stack<>();
        Queue.add(s);
        S.add(s);
        for(int i = 1;i <= n;++i) {
            cnt2[i] = 1;
            cnt[i] = 0;
        }
        cnt[s] = 1;
        while(!Queue.isEmpty()) {
            int u = Queue.poll();
            for(Edge v : edges[u]) {
                if(v.tag == 0) continue;
                in[v.to]--;
                cnt[v.to] += cnt[u];
                cnt[v.to] %= Mod;
                if(in[v.to] == 0) {
                    Queue.add(v.to);
                    S.add(v.to);
                }
            }
        }
        while(!S.isEmpty()) {
            int u = S.pop();
            for(Edge v : edges[u]) {
                if(v.tag == 0) continue;
                cnt2[u] += cnt2[v.to];
                cnt2[u] %= Mod;
            }
        }
        for(int i = 1;i <= n;++i) {
            for(Edge v : edges[i]) {
                if(v.tag == 0) continue;
                ans[v.id] += cnt[i] * cnt2[v.to] % Mod;
                ans[v.id] %= Mod;
            }
        }
    }
    public static void main(String[] args) throws IOException {
        cin.nextToken();
        int n = (int) cin.nval;
        cin.nextToken();
        int m = (int) cin.nval;
        init(n);
        for(int i = 1;i <= m;++i) {
            cin.nextToken();
            int u = (int) cin.nval;
            cin.nextToken();
            int v = (int) cin.nval;
            cin.nextToken();
            int w = (int) cin.nval;
            edges[u].add(new Edge(v,w,0,i));
        }
        for(int i = 1;i <= n;++i) {
            dijkstra(i,n);
        }
        for(int i = 1;i <= m;++i) {
            out.println(ans[i]);
        }
        out.close();
    }
}
View Code

 

posted @ 2022-03-01 18:43  levill  阅读(26)  评论(0编辑  收藏  举报