[题解]UVA10269 Adventure of Super Mario

链接:http://vjudge.net/problem/viewProblem.action?id=24902

描述:由城镇、村子和双向边组成的图,从A+B走到1,要求最短路。有K次瞬移的机会,距离不超过L,且不能经过城镇。

思路:一个图上的DP。首先floyd处理,然后做dp。

        定义f[i][j]:从1到i还有j次瞬移机会,花费的最少的时间。

        状态转移:f[i][j]=min{f[k][j]+dis[k][i],min{f[k][j-1]}}

        边界处理:f[1][k]=0 和 f[i][0]=dis[1][i]

 

我的实现:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 #define MaxN 120
 6 #define INF 100000
 7 int f[MaxN][MaxN],dis[MaxN][MaxN];
 8 bool OK[MaxN][MaxN];
 9 int T,n,A,B,M,L,K;
10 inline void Get_int(int &Ret)
11 {
12     char ch;
13     bool flag=false;
14     for(;ch=getchar(),ch<'0'||ch>'9';)
15         if(ch=='-')
16             flag=true;
17     for(Ret=ch-'0';ch=getchar(),ch>='0'&&ch<='9';Ret=Ret*10+ch-'0');
18     flag&&(Ret=-Ret);
19 }
20 inline void Read_Clean()
21 {
22     Get_int(A);Get_int(B);Get_int(M);Get_int(L);Get_int(K);
23     n=A+B;
24     memset(dis,0x3f,sizeof(dis));
25     memset(OK,false,sizeof(OK));
26     memset(f,0,sizeof(f));
27     int i,x,y,l;
28     for(i=1;i<=M;++i)
29     {
30         Get_int(x);Get_int(y);Get_int(l);
31         dis[x][y]=dis[y][x]=l;
32         if(l<=L)
33             OK[x][y]=OK[y][x]=true;
34     }
35 }
36 void floyd()
37 {
38     int i,j,k;
39     for(k=1;k<=n;++k)
40         for(i=1;i<=n;++i)
41             for(j=1;j<=n;++j)
42                 if(dis[i][j]>dis[i][k]+dis[k][j])
43                 {
44                     dis[i][j]=dis[i][k]+dis[k][j];
45                     if(k<=A&&dis[i][j]<=L)
46                         OK[i][j]=OK[j][i]=true;
47                 }
48 }
49 void DP()
50 {
51     int i,j,k,tmp;
52     for(i=2;i<=n;++i)
53         f[i][0]=dis[1][i];
54     for(i=2;i<=n;++i)
55     {
56         for(j=1;j<=K;++j)
57         {
58             tmp=INF;
59             for(k=1;k<i;++k)
60             {
61                 if(OK[k][i])
62                     tmp=min(tmp,f[k][j-1]);
63                 tmp=min(tmp,f[k][j]+dis[k][i]);
64             }
65             f[i][j]=tmp;
66         }
67     }
68     printf("%d\n",f[n][K]);
69 }
70 int main()
71 {
72     Get_int(T);
73     while(T--)
74     {
75         Read_Clean();
76         floyd();
77         DP();
78     }
79     return 0;
80 }
View Code

PS.破题出现了困难,最开始除了暴搜什么思路都没有。之后在暴搜的基础上发现了解题方法。总的来说觉得这道题蛮难的,zyy的路还很长啊~~~

转载于:https://www.cnblogs.com/CQBZOIer-zyy/p/3828872.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值