Luo Valley P1613 foot (shortest doubling + DP +)

Topic link: P1613 foot

The meaning of problems

Given comprising \ (n-\) points and \ (m \) have edges directed graph, the length of each side is \ (1 \) km. Per second run \ (2 ^ k \) kilometers from the point Q \ (1 \) point \ (n-\) take at least several seconds.

Thinking

Multiplying DP Floyd

Order \ (dp [i] [j ] [k] \) represents the \ (I \) to \ (J \) whether there is a length \ (2 ^ k \) path.

Then if \ (dp [i] [t ] [k - 1] \) and \ (dp [t] [j ] [k - 1] \) are \ (1 \) then \ (dp [i] [ j] [k] \) of \ (1 \) . At this time, the right side can be used as \ (1 \) side of the point \ (I \) and the point \ (J \) connected together.

The last run again the shortest path can be.

Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e2 + 10;

ll dp[maxn][maxn][maxn];
ll dis[maxn][maxn];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    memset(dis, 0x3f, sizeof(dis));
    int n, m;
    cin >> n >> m;
    for(int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        dp[x][y][0] = 1;
        dis[x][y] = 1;
    }
    for(int x = 1; x <= 64; ++x) {
        for(int k = 1; k <= n; ++k) {
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= n; ++j) {
                    if(dp[i][k][x - 1] && dp[k][j][x - 1]) {
                        dp[i][j][x] = 1;
                        dis[i][j] = 1;
                    }
                }
            }
        }
    }
    for(int k = 1; k <= n; ++k) {
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= n; ++j) {
                dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
            }
        }
    }
    cout << dis[1][n] << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/wulitaotao/p/11515526.html