1. 程式人生 > >最短路徑-並查集+Floyd[轉載]

最短路徑-並查集+Floyd[轉載]

pbo 忽略 lse logs describe asi 最短距離 學習 stack

題目描述

N個城市,標號從0到N-1,M條道路,第K條道路(K從0開始)的長度為2^K,求編號為0的城市到其他城市的最短距離

輸入描述:

第一行兩個正整數N(2<=N<=100)M(M<=500),表示有N個城市,M條道路
接下來M行兩個整數,表示相連的兩個城市的編號

輸出描述:

N-1行,表示0號城市到其他城市的最短路,如果無法到達,輸出-1,數值太大的以MOD 100000 的結果輸出。
示例1

輸入

復制
4 4
1 2
2 3
1 3
0 1

輸出

復制
8
9
11

https://www.cnblogs.com/lca1826/p/6748372.html 關於快速冪的講解
https://www.cnblogs.com/Asimple/p/6502632.html 代碼來自於這個
//Asimple
//#include <bits/stdc++.h>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cctype>
#include <cstdlib>
#include <stack>
#include <cmath>
#include <set
> #include <map> #include <string> #include <queue> #include <limits.h> #include <time.h> #define INF 0xfffffff #define mod 100000 #define PI 3.14159265358979323 #define swap(a,b,t) t = a, a = b, b = t #define CLS(a, v) memset(a, v, sizeof(a)) #define debug(a) cout << #a << " = " << a <<endl #define
dobug(a, b) cout << #a << " = " << a << " " << #b << " = " << b << endl using namespace std; typedef long long ll; const int maxn = 101; int n, m, num, T, k, len, ans, sum, x, y; int Map[maxn][maxn]; int fa[maxn]; ll qpow(ll a, ll b, ll md) {//這裏使用快速冪來計算2的k次方,並且每次都%md,保證不溢出 ll ans = 1; while( b ) { if( b & 1 ) ans = ans * a % md; a = a * a % md; b = b >> 1; } return ans; } int find(int x) { return x==fa[x]?x:fa[x]=find(fa[x]); } void solve() { x = find(0); for(int i=1; i<n; i++) { if( x!=find(i) ) cout << "-1" << endl;//如果不在一個集合裏,那麽就-1 else cout << Map[0][i] << endl; } } void input() { while( cin >> n >> m ) { for(int i=0; i<n; i++) { fa[i] = i; Map[i][i] = 0; } for(int i=0; i<m; i++) { cin >> x >> y; num = qpow(2, i, mod); int xx = find(x); int xy = find(y); if( xx==xy ) continue;//如果已經聯通了,那麽就忽略,因為後來的邊權值一定比原來的所有邊大,已經聯通就不用再放進來了。 for(int j=0; j<n; j++) { if( xx!=find(j) ) continue;//也就是找到當前集合的根 for(int k=0; k<n; k++) { if( xy!=find(k) ) continue; Map[j][k] = Map[k][j] = (Map[j][x] + num + Map[y][k])%mod; } } fa[xy] = xx; } solve(); } } int main(){ input(); return 0; }

//學習到了很多,b&1得到的結果只是個位與。==

最短路徑-並查集+Floyd[轉載]