[洛谷P1613]跑路
阿新 • • 發佈:2019-01-29
-- print register urn gin mes con using eof
題目傳送門
這道題題意不是很清楚。在翻看了幾個討論後,理清了題意。
這道題有環,有重邊,甚至可能一次性到終點,而整段路線繞著某個環跑好多圈。每次跳必須要到一個點。
然後這道題要倍增,來判斷從一個點是否能一次到另一個點。
所以設$e[i][j][k]$表示從第$i$個點是否存在一條路徑長為$2^k$到點$j$。
更新跟$Floyd$很相像,若$e[i][p][k-1] \ \&\&\ e[p][j][k-1]$為$1$,則$e[i][j][k]$為1。
然後點$i$到點$j$能否直接跳達就轉變成$e[i][j][1..32]$中是否有1。設成$32$是因為$2^32$符合題意$maxlongint$。
構圖跑最短路即可。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define re register 6 #define rep(i, a, b) for (re int i = a; i <= b; ++i) 7 #define repd(i, a, b) for (re int i = a; i >= b; --i) 8 #define maxx(a, b) a = max(a, b); 9 #define minn(a, b) a = min(a, b); 10#define LL long long 11 #define inf (1 << 30) 12 13 const int maxn = 50 + 5, maxk = 35; 14 15 inline int read() { 16 int w = 0, f = 1; char c = getchar(); 17 while (!isdigit(c)) f = c == ‘-‘ ? -1 : f, c = getchar(); 18 while (isdigit(c)) w = (w << 3) + (w << 1) + (c ^ ‘0‘), c = getchar(); 19 return w * f; 20 } 21 22 int n, m, e[maxn][maxn][maxk]; 23 LL E[maxn][maxn]; 24 25 int main() { 26 n = read(); m = read(); 27 memset(e, sizeof(e), 0); 28 memset(E, sizeof(E), 0); 29 rep(i, 1, m) { 30 int u = read(), v = read(); 31 e[u][v][0] = 1; 32 } 33 rep(k, 1, maxk - 1) 34 rep(p, 1, n) 35 rep(i, 1, n) 36 rep(j, 1, n) 37 e[i][j][k] |= e[i][p][k-1] & e[p][j][k-1]; 38 39 rep(i, 1, n) 40 rep(j, 1, n) { 41 rep(k, 0, maxk - 1) 42 E[i][j] |= e[i][j][k]; 43 E[i][j] = E[i][j] ? 1 : (1LL << 40); 44 } 45 46 rep(k, 1, n) 47 rep(i, 1, n) 48 rep(j, 1, n) 49 if (i != k && j != k) 50 minn(E[i][j], E[i][k] + E[k][j]); 51 52 printf("%lld", E[1][n]); 53 return 0; 54 }
[洛谷P1613]跑路