zoukankan      html  css  js  c++  java
  • [题解]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
    ",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的路还很长啊~~~

  • 相关阅读:
    线程池
    非XA式Spring分布式事务
    好的架构不是设计出来的,而是演进出来的
    缓存穿透
    【转】MySQL数据库主从同步管理
    setup 桌面化设置网卡
    gitlab web登入密码忘记以后可以用如下方式修改密码
    kvm与selinux
    linux下跳板机跟客户端之间无密码登陆
    LINUX下安装TeamViewer
  • 原文地址:https://www.cnblogs.com/CQBZOIer-zyy/p/3828872.html
Copyright © 2011-2022 走看看