[题解]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的路还很长啊~~~

posted @ 2014-07-06 23:49  zyy是一只超级大沙茶  阅读(231)  评论(0编辑  收藏  举报