UVA10269 Adventure of Super Mario(dijkstra)

题意:

再次成功营救出桃子公主之后,马里奥需要从Bowser魔王的城堡返回他的家。马里奥世界里一共有A个村庄和B个城堡(1<=A,B<=50),其中村庄编号为1到A,城堡编号为A+1到A+B。马里奥住在村庄1,而Bowser住在城堡A+B。

马里奥能以1公里/小时的速度沿着村庄和城堡之间的双向道路行走,也可以用魔法鞋加速。魔法鞋可以让马里奥瞬间移动不超过L(L<=50)公里,但由于城堡中有很多陷阱,稍不留神就会中招,因此马里奥不使用魔法鞋穿过城堡。另外,使用魔法鞋的起点和终点都只能是城堡或者村庄,且最多只能使用K(K<=10)次魔法鞋。 你的任务是计算马里奥回家的最短时间。输入保证马里奥一定能回家。

分析:不使用魔法鞋穿过城堡没看懂啊啊啊啊啊啊啊,,理解能力太弱了!!!

因为不使用魔法鞋穿过城堡,所有算最短路时,中间结点不能是城堡!先用floyd算法,将每个点使用魔法鞋能去的地方算出来(先不考虑距离约束).

接下来就是dijkstra算法,算出A+B点到1点所花费的最短时间,因为可以使用K次魔法,故每个点的状态是K+1次,V[u][k]是指A+B到达u点,还有k次魔法没用使用花费的时间..

然后用优先队列,最先出来的终点所花费的时间即是答案!

// File Name: 10269.cpp
// Author: Zlbing
// Created Time: 2013/4/16 22:04:15

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)
const int MAXN=105;
int A,B,M,L,K;
struct node
{
    int u,cost,k;
    bool operator <(const node& a)const
    {
        return cost>a.cost;
    }
};
int G[MAXN][MAXN];
int V[MAXN][MAXN];
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][k]+G[k][j]<G[i][j])
                    G[i][j]=G[i][k]+G[k][j];
            }
}
int dijkstra()
{
    CL(V,-1);
    priority_queue<node>Q;
    node a;
    a.u=A+B;
    a.cost=0;
    a.k=K;
    Q.push(a);
    REP(i,0,K)
    V[A+B][i]=0;
    while(!Q.empty())
    {
        node t=Q.top();
        Q.pop();
        int u=t.u;
        int cost=t.cost;
        int k=t.k;
        if(u==1)return cost;
        node tt;
        for(int i=1; i<=A+B; i++)
        {
            if(G[u][i]!=INF&&u!=i)
            {
                if(G[u][i]<=L&&(V[i][k-1]==-1||V[i][k-1]>cost)&&k>0)
                {
                    V[i][k-1]=cost;
                    tt.u=i;
                    tt.cost=cost;
                    tt.k=k-1;
                  //  printf("--a----\n");
                  //  printf("u%d cost%d k%d\n",tt.u,tt.cost,tt.k);
                    Q.push(tt);
                }
                if(V[i][k]==-1||V[i][k]>cost+G[u][i])
                {
                    V[i][k]=cost+G[u][i];
                    tt.u=i;
                    tt.cost=cost+G[u][i];
                    tt.k=k;
                  //  printf("--a----\n");
                  //  printf("u%d cost%d k%d\n",tt.u,tt.cost,tt.k);
                    Q.push(tt);
                }
            }
        }
    }
    return -1;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d%d%d",&A,&B,&M,&L,&K);
        REP(i,1,A+B)
        REP(j,1,A+B)
        G[i][j]=INF;
        REP(i,1,M)
        {
            int a,b,c;
            scanf("%d%d%d",&a,&b,&c);
            G[a][b]=c;
            G[b][a]=c;
        }
        floyd();
        int ans=dijkstra();
        printf("%d\n",ans);
    }
    return 0;
}

 

原文地址:https://www.cnblogs.com/arbitrary/p/3026659.html