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

来源:互联网 发布:mac装win10设置电源 编辑:程序博客网 时间:2024/05/29 19:32

题目

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;}


0 0
原创粉丝点击