• ZOJ1232 Adventure of Super Mario(DP+SPFA)


    dp[u][t]表示从起点出发,到达i点且用了t次magic boot时的最短时间,

    方程如下:

    dp[v][t]=min(dp[v][t],dp[u][t]+dis[u][v]);

    dp[v][t]=min(dp[v][t],dp[u][t-1]) (dis[u][v]<=l)

    放进SPFA更新,相当于一个二维的最短路,解决DP在非DAG下的有后效性的问题。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<queue>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXN 111
     7 #define INF (1<<29)
     8 
     9 int n,a,b,m,l,k;
    10 int map[MAXN][MAXN],dis[MAXN][MAXN];
    11 
    12 void Floyd(){
    13     memcpy(dis,map,sizeof(map));
    14     for(int k=1; k<=a; ++k){
    15         for(int i=1; i<=n; ++i){
    16             for(int j=1; j<=n; ++j){
    17                 if(dis[i][k]==INF || dis[k][j]==INF) continue;
    18                 dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
    19             }
    20         }
    21     }
    22 }
    23 
    24 struct QNode{
    25     int u,t;
    26     QNode(int _u=0,int _t=0):u(_u),t(_t){}
    27 };
    28 int dp[MAXN][11];
    29 bool vis[MAXN][11];
    30 void SPFA(){
    31     memset(vis,0,sizeof(vis));
    32     vis[n][0]=1;
    33     for(int i=1; i<=n; ++i){
    34         for(int j=0; j<11; ++j) dp[i][j]=INF;
    35     }
    36     dp[n][0]=0;
    37     queue<QNode> que;
    38     que.push(QNode(n,0));
    39     while(!que.empty()){
    40         int u=que.front().u,t=que.front().t;
    41         que.pop();
    42         for(int v=1; v<=n; ++v){
    43             if(dp[v][t]>dp[u][t]+dis[u][v]){
    44                 dp[v][t]=dp[u][t]+dis[u][v];
    45                 if(!vis[v][t]){
    46                     vis[v][t]=1;
    47                     que.push(QNode(v,t));
    48                 }
    49             }
    50         }
    51         for(int v=1; t!=k && v<=n; ++v){
    52             if(dis[u][v]<=l && dp[v][t+1]>dp[u][t]){
    53                 dp[v][t+1]=dp[u][t];
    54                 if(!vis[v][t+1]){
    55                     vis[v][t+1]=1;
    56                     que.push(QNode(v,t+1));
    57                 }
    58             }
    59         }
    60         vis[u][t]=0;
    61     }
    62 }
    63 
    64 int main(){
    65     int t,u,v,w;
    66     scanf("%d",&t);
    67     while(t--){
    68         scanf("%d%d%d%d%d",&a,&b,&m,&l,&k);
    69         n=a+b;
    70         for(int i=1; i<=n; ++i){
    71             for(int j=1; j<=n; ++j) map[i][j]=INF;
    72         }
    73         while(m--){
    74             scanf("%d%d%d",&u,&v,&w);
    75             map[u][v]=map[v][u]=min(map[u][v],w);
    76         }
    77         Floyd();
    78         SPFA();
    79         int res=INF;
    80         for(int i=0; i<=k; ++i){
    81             res=min(res,dp[1][i]);
    82         }
    83         printf("%d
    ",res);
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    Sum Root to Leaf Numbers深度优先计算路径和
    Path Sum II深度优先找路径
    动态和静态链接库
    C/C++变量
    搜索
    基本格式
    随机数生成函数
    珍惜生命,我用Python 。今天开始学习Python
    在windows里hexo 博客创建步骤
    作为一个程序员,什么是脚本。必须要理解
  • 原文地址:https://www.cnblogs.com/WABoss/p/5090670.html
Copyright © 2020-2023  润新知