#include #include #include #include #include #include #include using std::cin; using std::cout; const char endl = '\n'; const int N = 1505, M = 5005; const int INF = 0x3f3f3f3f; const int mod = 1e9 + 7; int n, m, dist[N], deg[N], cnt_in[N], cnt_out[N], ans[M]; std::vector> g[N]; std::tuple edges[M]; bool vis[N]; void dijkstra(int s) { std::fill(std::begin(dist), std::end(dist), INF); std::fill(std::begin(vis), std::end(vis), false); std::priority_queue< std::pair, std::vector>, std::greater<>> q; q.emplace(0, s); dist[s] = 0; while (!q.empty()) { int u = q.top().second; q.pop(); if (vis[u]) continue; for (auto e : g[u]) { int v, w; std::tie(v, w, std::ignore) = e; if (dist[v] > dist[u] + w) { dist[v] = dist[u] + w; q.emplace(dist[v], v); } } vis[u] = true; } } void topo(int s) { std::fill(std::begin(deg), std::end(deg), 0); std::fill(std::begin(cnt_in), std::end(cnt_in), 0); std::fill(std::begin(cnt_out), std::end(cnt_out), 0); for (int i = 1; i <= m; i++) { if (std::get<3>(edges[i])) { deg[std::get<1>(edges[i])]++; } } std::queue q; std::vector v; cnt_in[s] = 1; q.emplace(s); while (!q.empty()) { int u = q.front(); v.emplace_back(u); q.pop(); for (auto e : g[u]) { int v, w, id; std::tie(v, w, id) = e; if (std::get<3>(edges[id])) { cnt_in[v] = (static_cast(cnt_in[v]) + cnt_in[u]) % mod; if (--deg[v] == 0) { q.emplace(v); } } } } std::for_each(v.rbegin(), v.rend(), [&](int u) { for (auto e : g[u]) { int v, w, id; std::tie(v, w, id) = e; if (std::get<3>(edges[id])) { cnt_out[u] = (static_cast(cnt_out[u]) + cnt_out[v]) % mod; } } cnt_out[u] = (cnt_out[u] + 1) % mod; }); } int main() { std::ios::sync_with_stdio(false); cin.tie(nullptr); cin >> n >> m; for (int i = 1, u, v, w; i <= m; i++) { cin >> u >> v >> w; g[u].emplace_back(v, w, i); edges[i] = {u, v, w, false}; } for (int i = 1; i <= n; i++) { dijkstra(i); std::for_each( std::begin(edges) + 1, std::begin(edges) + m + 1, [&](auto &e) { int u = std::get<0>(e), v = std::get<1>(e), w = std::get<2>(e); std::get<3>(e) = dist[u] + w == dist[v]; }); topo(i); for (int j = 1; j <= m; j++) { int u, v; bool is_short; std::tie(u, v, std::ignore, is_short) = edges[j]; if (is_short) { ans[j] = (static_cast(ans[j]) + static_cast(cnt_in[u]) * cnt_out[v] % mod) % mod; } } } std::copy_n(std::begin(ans) + 1, m, std::ostream_iterator(cout, "\n")); return 0; }