-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbzoj-2750.cpp
64 lines (64 loc) · 1.46 KB
/
bzoj-2750.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <algorithm>
#include <cstdio>
#include <vector>
#include <queue>
using namespace std;
const int N = 1520, M = 5050, INF = 2e9 + 10, mod = 1e9 + 7;
struct Edge { int v, w; };
vector<Edge> G[M];
struct Node {
int u, d;
bool operator < (const Node &b) const {
return d > b.d;
}
};
int n, m, d[N], f[N], g[N], uu[M], vv[M], ww[M], h[M];
int dp(int u) {
if(g[u]) return g[u];
g[u] = 1;
for(int i = 0; i < (int) G[u].size(); i ++) {
Edge &e = G[u][i];
if(e.w + d[u] == d[e.v]) {
(g[u] += dp(e.v)) %= mod;
}
}
return g[u];
}
void Dijkstra(int s) {
fill(d + 1, d + n + 1, INF);
priority_queue<Node> pq;
pq.push((Node) {s, d[s] = 0});
fill(f + 1, f + n + 1, 0); f[s] = 1;
while(pq.size()) {
int u = pq.top().u, du = pq.top().d; pq.pop();
if(d[u] < du) continue ;
for(int i = 0; i < (int) G[u].size(); i ++) {
Edge &e = G[u][i];
if(d[e.v] > d[u] + e.w) {
d[e.v] = d[u] + e.w; f[e.v] = f[u];
pq.push((Node) {e.v, d[e.v]});
} else if(d[e.v] == d[u] + e.w) {
(f[e.v] += f[u]) %= mod;
}
}
}
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 1; i <= m; i ++) {
scanf("%d%d%d", uu + i, vv + i, ww + i);
G[uu[i]].push_back((Edge) {vv[i], ww[i]});
}
for(int i = 1; i <= n; i ++) {
Dijkstra(i);
fill(g + 1, g + n + 1, 0); dp(i);
for(int j = 1; j <= m; j ++) {
if(d[uu[j]] + ww[j] == d[vv[j]]) {
(h[j] += 1ll * f[uu[j]] * g[vv[j]] % mod) %= mod;
}
}
}
for(int i = 1; i <= m; i ++)
printf("%d\n", h[i]);
return 0;
}