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 need a
map, he only needs the best route in order to save time.

There are A Villages and B Castles in the world. Villages are numbered 1..A, and Castles are numbered A+1..A+B. Mario lives in Village 1, and the castle he starts from is numbered A+B. Also, there are two-way roads connecting them. Two places are connected
by at most one road and a place never has a road connecting to itself. Mario has already measured the length of every road, but they don‘t want to walk all the time, since he walks one unit time for one unit distance(how slow!).

Luckily, in the Castle where he saved the princess, Mario found a magic boot. If he wears it, he can super-run from one place to another IN NO TIME. (Don‘t worry about the princess, Mario
has found a way to take her with him when super-running, but he wouldn‘t tell you :-P)

Since there are traps in the Castles, Mario NEVER super-runs through a Castle. He always stops when there is a castle on the way. Also, he starts/stops super-runnings ONLY at Villages
or Castles.

Unfortunately, the magic boot is too old, so he cannot use it to cover more than L kilometers at a time, and he cannot use more than K times in total. When he comes back home, he can
have it repaired and make it usable again.

Input

The first line in the input contains a single integer T, indicating the number of test cases. (1<=T<=20) Each test case begins with five integers A, B, M, L and K -- the number of Villages,
the number of Castles(1<=A,B<=50), the number of roads, the maximal distance that can be covered at a time(1<=L<=500), and the number of times the boot can be used. (0<=K<=10) The next M lines each contains three integers Xi, Yi, Li. That means there is a
road connecting place Xi and Yi. The distance is Li, so the walk time is also Li. (1<=Li<=100)

Output

For each test case in the input print a line containing a single integer indicating the minimal time needed to go home with the beautiful princess. It‘s guaranteed that Super Mario can
always go home.

Sample Input

1

4 2 6 9 1

4 6 1

5 6 10

4 5 5

3 5 4

2 3 4

1 2 3

Sample Output

9

题意:给定N个点求1-N的最短路,所加的附加条件就是这N个点前A个点为村庄,后B个点为城堡。马里奥用一双靴子,能够在一定距离(L)内花0时间进行穿梭,且只有K次机会,但使用鞋子时不能穿过城堡。在这种情况下,求解一个最短路。

思路:先用Floyd求得任意两点间距离,然后,枚举每个点,具体看代码吧。。。

#include"stdio.h"
#include"string.h"
#include"iostream"
#include"algorithm"
using namespace std;
#define N 105
const int inf=1000000;
int can[N][N],e[N][N],dp[N][11];
int min(int a,int b)
{
    return a<b?a:b;
}
int main()
{
    int T,a,b,l,m,n,K;
    int i,j,k,u,v,d;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d",&a,&b,&m,&l,&K);
        n=a+b;
        for(i=1;i<=n;i++)  //数组初始化,
        {
            for(j=1;j<=n;j++)
            {
                e[i][j]=(i==j?0:inf);
                can[i][j]=0;
            }
        }
        for(i=0;i<m;i++)
        {
            scanf("%d%d%d",&u,&v,&d);
            e[u][v]=e[v][u]=d;
            if(d<=l)
                can[u][v]=can[v][u]=1;
        }
        for(k=1;k<=n;k++)      //floyd算法求任意两点间最短路
        {
            for(i=1;i<=n;i++)
            {
                for(j=1;j<=n;j++)
                {
                    if(e[i][j]>e[i][k]+e[k][j])
                    {
                        e[i][j]=e[i][k]+e[k][j];
                        if(e[i][j]<=l&&k<=a)
                            can[i][j]=1;
                    }
                }
            }
        }
        for(i=1;i<=n;i++)
            dp[i][0]=e[1][i];
        for(i=2;i<=n;i++)
        {
            for(j=1;j<=K;j++)
            {             //dp[i][j]代表通过前i-1个点走到第 i 点,用了j次鞋子的最少时间;
                int tmp=inf;  //枚举在前i个点在[k,i]这一段使用第j次鞋子,用的最少时间
                for(k=1;k<i;k++)     //tmp记录该值
                {
                    if(can[k][i])
                    {
                        tmp=min(tmp,min(dp[k][j-1],dp[k][j]+e[k][i]));
                    }      //在[k,i]这段使用第j次鞋子,不使用鞋子的最小值
                    else
                        tmp=min(tmp,dp[k][j]+e[k][i]);
                }
                dp[i][j]=tmp;
            }
        }
        printf("%d\n",dp[n][K]);
    }
    return 0;
}
时间: 2024-11-05 04:51:42

zoj 1232 Adventure of Super Mario (Floyd+dp)的相关文章

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号村

ZOJ 1232 Adventure of Super Mario

最短路+DP(个人用的SPFA+完全背包) 做了一上午--开始想用SPFA+BFS.但是写了半天越写越乱,放弃了. 就想到了是不是可以当作背包问题(背出病了--)把鞋子可以使用的次数当作背包容量.做完全背包. 先N次SPFA把 各点的最短距离算出来,其实比较适合Floyd.(个人用vector实现伪邻接表,然后SPFA) 然后SPFA更新路径的时候,当鞋子使用次数不为0的时候,做完全背包. 还有个忧伤的地方就是我把INF=0x7fffffff.结果加上一个数 变成负数了.一直不对. 找了半天,最

ZOJ 1232 Adventure of Super Mario SPFA+DP

第一次做类似的题目,卡了好几天,最后看了爱酱的blog(http://blog.csdn.net/acm_cxlove/article/details/8679230)才会的,sad 题意大概是这样,给你一个图,求起点1到N的最短时间,你有一双鞋子,可以加速,一次性花费0的时间行走M单位的路程,但是鞋子只能用K次,并且鞋子使用的时候起点和终点都必须在节点上,不能在半路停下.并且使用的鞋子的时候不能穿过编号大于A的节点,在不使用鞋子的情况下行走单位路程花费单位时间. dp[i][k]表示从起点到i

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

HDU2833 WuKong(floyd + dp)经典

WuKong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1429    Accepted Submission(s): 517 Problem Description Liyuan wanted to rewrite the famous book "Journey to the West" ("Xi You