方法一:弗洛伊德+并查集
#include <iostream> #include <algorithm> #include <cstring> using namespace std; const int N = 110, MOD = 100000, INF = 0x3f3f3f3f; int n, m; int p[N]; int d[N][N]; int find(int x) { if(p[x] != x) p[x] = find(p[x]); return p[x]; } int main() { cin >> n >> m; for(int i = 0; i < n; i ++ ) p[i] = i; memset(d, 0x3f, sizeof d); for(int i = 0; i < n; i ++ ) d[i][i] = 0; for(int i = 0, len = 1; i < m; i ++, len = len * 2 % MOD) { int a, b; cin >> a >> b; if(find(a) != find(b)) { p[find(a)] = find(b); d[a][b] = d[b][a] = len; } } for(int k = 0; k < n; k ++ ) for(int i = 0; i < n; i ++ ) for(int j = 0; j < n; j ++ ) d[i][j] = min(d[i][j], d[i][k] + d[k][j]); for(int i = 1; i < n; i ++ ) if(d[0][i] == INF) puts("-1"); else cout << d[0][i] % MOD << endl; return 0; }
方法二:堆优化Dijkstra +并查集+快速幂
#include <iostream> #include <algorithm> #include <cstring> #include <queue> using namespace std; typedef long long LL; typedef pair<int, int> PII; const int N = 110, M = 500 * 2 + 10, mod = 100000; int n, m, id; int h[N], e[M], ne[M], w[M], idx; int dist[N]; int p[N]; bool st[N]; void add(int a, int b, int c) { e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx ++ ; } int find(int x) { if (p[x] != x) p[x] = find(p[x]); return p[x]; } LL qmi(LL a, int k) { LL res = 1; while (k) { if (k & 1) res = res * a % mod; k >>= 1; a = a * a % mod; } return res; } void dijkstra() { memset(dist, 0x3f, sizeof dist); dist[0] = 0; // 点的标号从0开始 priority_queue<PII, vector<PII>, greater<PII>> heap; heap.push({0, 0}); // 第二位是点的编号,第一位是距离 while (heap.size()) { PII t = heap.top(); heap.pop(); int ver = t.second, distance = t.first; if (st[ver]) continue; st[ver] = true; for (int i = h[ver]; i != -1; i = ne[i]) { int j = e[i]; if (dist[j] > distance + w[i]) { dist[j] = distance + w[i]; heap.push({dist[j], j}); } } } } int main() { scanf("%d%d", &n, &m); memset(h, -1, sizeof h); for (int i = 0; i < n; i ++ ) p[i] = i; while (m -- ) { int a, b; scanf("%d%d", &a, &b); int c = qmi(2, id); id ++ ; if (find(a) != find(b)) { p[find(a)] = find(b); add(a, b, c); add(b, a, c); } } dijkstra(); for (int i = 1; i < n; i ++ ) { if (dist[i] == 0x3f3f3f3f) puts("-1"); else printf("%d\n", dist[i] % mod); } return 0; }