1. 程式人生 > >【luogu P1613】跑路

【luogu P1613】跑路

== 數組 pro nbsp 推出 for cst fine return

https://www.luogu.org/problem/show?pid=1613

看到2k就能想到倍增。用一個數組avai[i][j][k]表示點i與點j是否存在長2k的路徑,則可以遞推出avai[i][j][k]=any{avai[i][v][k-1]&avai[v][j][k-1]},初始值avai[i][i][0]=true。如果avai[i][j][k]==true,則在i點與j點加一條長1的路徑。最後BFS或者直接Floyd跑一遍最短路徑就可以了。

#include <iostream>
#include <vector>
#include <queue>
#include 
<cstring> #define maxn 55 using namespace std; int n, m; int g[maxn][maxn]; bool avai[maxn][maxn][65]; int main() { ios::sync_with_stdio(false); memset(g, 0x3f, sizeof(g)); cin >> n >> m; int u, v; for (int i = 1; i <= m; i++) { cin >> u >> v; avai[u][v][
0] = g[u][v] = 1; } for (int i = 1; i <= n; i++) g[i][i] = 1; //f(i,j,k)=f(i,v,k-1)&&f(v,j,k-1) for (int k = 1; k <= 64; k++) { for (int u = 1; u <= n; u++) { for (int v = 1; v <= n; v++) { for (int
w = 1; w <= n; w++) { if (avai[u][v][k] |= avai[u][w][k - 1] == 1 && avai[w][v][k - 1] == 1) g[u][v] = 1; } } } } for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) g[i][j] = min(g[i][k] + g[k][j], g[i][j]); cout << g[1][n] << endl; return 0; }

【luogu P1613】跑路