《最短路径树》
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(); } }