[LA 6751 Mixed Flight Plans] Floyd+图上按链DP

题目

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&category=607&page=show_problem&problem=4763

分析

Floyd+图上按链DP

对于每条链,从起点到其他所有点连边,求floyd

首先只有两种情况,一是A>B,C->D,这种情况直接floyd就可以

另一情况时A->D,C->B,这种情况要求交于一点,又要保证沿着链走,所以枚举一条链,然后在链上做DP

设f[i][0]表示A->D与C->B相交在i的A->D的最短距离

设f[i][1]表示C->B与A->D相交在i的C->B的最短距离

那么转移方程:

f[i][0]=min{dist[A][src]+cost[x]+dist[next][D]}

f[i][1]=min{dist[C][src]+cost[x]+dist[next][B]}

x为枚举的链,src为链的起点,next为i在链上的后继

最后答案为min{dist[A][B]+dist[C][D],min{dist[A][i]+dist[i][D],f[i][0]}+min{dist[C][i]+dist[i][B],f[i][1]}}

时间复杂度O(NL)

L为所有链的总长度

代码

/**************************************************
 *        Problem:  LA 6751
 *         Author:  clavichord93
 *          State:  Accepted
 **************************************************/

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
using namespace std;
const int INF = 0x3f3f3f3f;

template <class T>
inline void gmin(T &a, T b) {
    if (a > b) {
        a = b;
    }
}

const int MAX_N = 105;
const int MAX_M = 10005;

int n, m;
int A, B, C, D;
int cost[MAX_M];
vector<int> flight[MAX_M];

int graph[MAX_N][MAX_N];
int f[MAX_N][2];

int main() {
    #ifdef LOCAL_JUDGE
    freopen("in.txt", "r", stdin);
    #endif
    while (scanf("%d %d %d %d %d %d", &n, &m, &A, &B, &C, &D), n || m || A || B || C || D) {
        memset(graph, 0x3f, sizeof(graph));
        for (int i = 1; i <= n; i++) {
            graph[i][i] = 0;
        }

        for (int i = 0; i < m; i++) {
            int cnt, src;
            scanf("%d %d %d", &cost[i], &cnt, &src);
            flight[i].clear();
            flight[i].push_back(src);
            for (int j = 0; j < cnt; j++) {
                int dst;
                scanf("%d", &dst);
                flight[i].push_back(dst);
                gmin(graph[src][dst], cost[i]);
            }
        }

        for (int k = 1; k <= n; k++) {
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++) {
                    gmin(graph[i][j], graph[i][k] + graph[k][j]);
                }
            }
        }

        memset(f, 0x3f, sizeof(f));
        for (int i = 0; i < m; i++) {
            int src = flight[i][0];
            int size = flight[i].size();
            int dp0 = INF;
            int dp1 = INF;
            for (int j = size - 1; j >= 0; j--) {
                int dst = flight[i][j];
                gmin(dp0, graph[A][src] + cost[i] + graph[dst][D]);
                gmin(f[dst][0], dp0);
                gmin(dp1, graph[C][src] + cost[i] + graph[dst][B]);
                gmin(f[dst][1], dp1);
            }
        }

        int ans = INF;
        gmin(ans, graph[A][B] + graph[C][D]);
        for (int i = 1; i <= n; i++) {
            gmin(ans, min(graph[A][i] + graph[i][D], f[i][0]) + min(graph[C][i] + graph[i][B], f[i][1]));
        }
        if (ans == INF) {
            printf("Impossible!\n");
        }
        else {
            printf("%d\n", ans);
        }
    }

    return 0;
}


你可能感兴趣的:([LA 6751 Mixed Flight Plans] Floyd+图上按链DP)