码迷,mamicode.com
首页 > 其他好文 > 详细

uva 10269 Adventure of Super Mario (floyd + dijkstra)

时间:2015-08-05 12:57:32      阅读:146      评论:0      收藏:0      [点我收藏+]

标签:

uva 10269 Adventure of Super Mario

题目大意:有A个村庄,B座城堡,村庄编号从1~A, 城堡编号从A + 1 ~ A + B。马里奥住在1号村庄,公主被关在A + B号城堡。马里奥有一件宝物,可以让他瞬间跑过L的距离,但是这件宝物是有限制的。发动这件宝物的起点或终点必须是村庄或者城堡,并且不能穿过城堡。这样的宝物当然不能随便用,所以它的耐久度只有K,也就是最多只能有K次,就要拿到铁匠铺去修理了。现在,马里奥已经在A + B号城堡救到公主了,问马里奥最快返回1号村庄的时间是多少。

解题思路:先用floyd处理一遍所有边,把可以优化的边优化一下(中点为城堡则不能优化,把k从1遍历到A就行了,i和j还是1~A + B),为后面使用装备技能做准备。然后用dijkstra求最短时间。把d[i][j]数组,开成二维的,i代表从起点到i号点所花的最短时间,j表示在当前情况下使用了几次技能,所以两个判断为d[i][k] > d[u][k] + G[u][i]G[u][i] <= L && d[i][k - 1] > d[u][k] && k != 0。dijkstra再用优先队列优化一下,当第一次到达1号村庄时,就可以得到答案。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;

const int N = 155;
const int INF = 0x3f3f3f3f;
typedef long long ll;
int A, B, M, L, K;
int G[N][N];

void floyd() {
    for (int k = 1; k <= A; k++) {
        for (int i = 1; i <= A + B; i++) {
            for (int j = 1; j <= A + B; j++) {
                if (G[i][j] > G[i][k] + G[k][j]) {
                    G[i][j] = G[i][k] + G[k][j];    
                }
            }   
        }   
    }
}

struct Node{
    int u, k, cos;
    bool operator <(const Node& a)const {
        return cos > a.cos;
    }
};
int d[N][15];
int dijkstra() {
    priority_queue<Node> Q;
    for (int i = 0; i <= A + B; i++) {
        for (int j = 0; j <= 12; j++) {
            d[i][j] = INF;  
        }
    }
    Q.push((Node){A + B, K, 0});
    d[A + B][K] = 0;
    while (!Q.empty()) {
        int u = Q.top().u;  
        int k = Q.top().k;
        if (u == 1) return Q.top().cos;
        Q.pop();
        for (int i = 1; i <= A + B; i++) {
            if (i == u) continue;   
            if (G[u][i] == INF) continue;
            if (d[i][k] > d[u][k] + G[u][i]) {
                d[i][k] = d[u][k] + G[u][i];
                Q.push((Node){i, k, d[i][k]});  
            }
            if (G[u][i] <= L && d[i][k - 1] > d[u][k] && k != 0) {
                d[i][k - 1] = d[u][k];  
                Q.push((Node){i, k - 1, d[i][k - 1]});
            }
        }
    }
}

void input() {
    scanf("%d %d %d %d %d", &A, &B, &M, &L, &K);    
    for (int i = 1; i <= A + B; i++) {
        for (int j = 1; j <= A + B; j++) {
            G[i][j] = INF;  
        }   
    }
    int a, b, c;
    for (int i = 0; i < M; i++) {
        scanf("%d %d %d", &a, &b, &c);
        G[a][b] = G[b][a] = c; 
    }
    floyd();
}

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        input();    
        printf("%d\n", dijkstra());
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许也可以转载,不过要注明出处哦。

uva 10269 Adventure of Super Mario (floyd + dijkstra)

标签:

原文地址:http://blog.csdn.net/llx523113241/article/details/47293883

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!