uva 10269 Adventure of Super Mario (floyd + dijkstra)

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

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

时间: 2024-08-28 17:46:50

uva 10269 Adventure of Super Mario (floyd + dijkstra)的相关文章

zoj 1232 Adventure of Super Mario (Floyd+dp)

Adventure of Super Mario Time Limit: 2 Seconds      Memory Limit: 65536 KB After rescuing the beautiful princess, Super Mario needs to find a way home -- with the princess of course :-) He's very familiar with the 'Super Mario World', so he doesn't n

UVA 10269 Adventure of Super Mario

主要时floyd判断出利用飞鞋生成的DIS .其他SPFA或DIJKSTRA都可以 #include <map> #include <set> #include <list> #include <cmath> #include <ctime> #include <deque> #include <stack> #include <queue> #include <cctype> #include &

HDU 4417 Super Mario (划分树)(二分)

Super Mario Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 6077    Accepted Submission(s): 2645 Problem Description Mario is world-famous plumber. His "burly" figure and amazing jumping ab

HDU4417 Super Mario(主席树)

题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4417 Description Mario is world-famous plumber. His “burly” figure and amazing jumping ability reminded in our memory. Now the poor princess is in trouble again and Mario needs to save his lover. We

HDU 4417:Super Mario(主席树)

http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意是:给出n个数和q个询问,每个询问有一个l,r,h,问在[l,r]这个区间里面有多少个数是小于等于h的. 思路:比较裸的主席树,注意题意给的区间是从[0,n-1],一开始看错导致想错了很多东西.询问的时候如果m < h,那么左子树全部都是小于 h 的,就加上左子树的 sum,继续查右子树,否则就查左子树.最后 l == r 的时候要判下 h >= l,因为这个也错了几次.从师兄那里学习到了如果找一

hdu 4417 Super Mario(主席树)

题意:给你一些数,有多次询问,问你在l,r区间内小于k的数有多少个 思路:主席树大发好,虽然树状数组和线段树离线也可以做 代码: #include <set> #include <map> #include <queue> #include <stack> #include <math.h> #include <vector> #include <string> #include <stdio.h> #incl

hdu 4417 Super Mario (主席树)

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4417 题意: 给你段长为n的序列,有q个询问,每次询问区间[l.r]内有多少个数小于等于k 思路: 之前用分块写过类似的,不过为了练习下主席树,这里用主席树写了下.思路很简单 离线离散化处理下,每次插入一个数num时,在主席树上下标num+1,这样每次询问[l,r]中有多少个小于k的数的时候,我们只要找下标[1,k]的区间第R次修改后的总和减去第L-1次修改后的总值就可以得到了 实现代码: #inclu

UVA10269 Adventure of Super Mario(Floyd+DP)

UVA10269 Adventure of Super Mario(Floyd+DP) After rescuing the beautiful princess, Super Mario needs to find a way home -- with the princess of course :-) He's very familiar with the 'Super Mario World', so he doesn't need a map, he only needs the be

zoj1232Adventure of Super Mario(图上dp)

题目连接: 啊哈哈,点我点我 思路: 这个题目是一个图上dp问题,先floyd预处理出图上所有点的最短路,但是在floyd的时候,把能够用神器的地方预处理出来,也就是转折点地方不能为城堡..预处理完毕后,就是一个dp问题了...dp[][],两维分别表示到达的地点和使用神器的次数..这样这个问题就得到了解决.. 题目: Adventure of Super Mario Time Limit: 2 Seconds      Memory Limit: 65536 KB After rescuing