• 《最短路径树》


    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
  • 相关阅读:
    05docker仓库---搭建本地仓库
    04docker容器操作
    03docker镜像
    02docker核心概念
    01docker基本概念
    find命令
    docker中ubuntu源更新慢加速 换为国内源 Debian10源
    计划任务 at & crond tbc
    mysql mysqladmin常用命令
    mariadb10安装
  • 原文地址:https://www.cnblogs.com/zwjzwj/p/15951823.html
Copyright © 2020-2023  润新知