#10064. 「一本通 3.1 例 1」黑暗城堡
阿新 • • 發佈:2021-07-25
這道題目還是很有意思的,叫什麼最短路徑生成樹。
顯然的一個做法就是用類似於prim的方法,維護一個已經和1聯通的集合以及所有點到1的最短路
然後按照距離dis的距離進行列舉,每次從集合裡找到可以在加進去之後令新點補全。
然後這個過程可以懶得維護,直接檢查每一個點和他周圍點就行了
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <vector> #include <queue> #define int long long using namespace std; int n, m; queue<int> q; int dis[1000001]; struct ed { int to; int v; } tem; vector<ed> v[1001]; int x, y, z; int vis[1001]; int mod = (1 << 31) - 1; void spfa() { int s = 1; q.push(s); memset(dis, 0x7f, sizeof(dis)); dis[s] = 0; while (!q.empty()) { int x = q.front(); q.pop(); vis[x] = 0; for (int i = 0; i < v[x].size(); ++i) { int vv = v[x][i].to; if (dis[vv] > dis[x] + v[x][i].v) { dis[vv] = dis[x] + v[x][i].v; if (!vis[vv]) { q.push(vv); vis[vv] = 1; } } } } } int ans = 1; signed main() { scanf("%d%d", &n, &m); for (int i = 1; i <= m; ++i) { scanf("%d%d%d", &x, &y, &z); v[y].push_back((ed) { x, z }); v[x].push_back((ed) { y, z }); } spfa(); for (int i = 2; i <= n; ++i) { int cnt = 0; for (int j = 0; j < v[i].size(); ++j) { if (dis[i] == dis[v[i][j].to] + v[i][j].v) { cnt++; } } ans *= cnt; ans %= mod; } cout << ans; return 0; }