zoukankan      html  css  js  c++  java
  • AC日记——[ZJOI2006]物流运输 bzoj 1003

    1003

    思路:

      最短路+dp;

      节点在a-b天里不能使用

      那么我们准备每一组a-b求一条最短路,如果没有,则用极大值表示;

      cost[a,b]记录这个最短路;

      然后,开始dp;

      dp[i]=min(dp[i],dp[j]+cost[j+1][i]*(i-j)+k);

      dp[i]表示前i天最小费用;

      最后输出dp[n]-k;

    来,上代码:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define ll long long
    
    ll n,m,k,e,map[25][25],cost[105][105],que[105*105*2],dp[105];
    
    bool if_[105][25];
    
    inline void in(ll &now)
    {
        register char Cget=getchar();now=0;
        while(Cget>'9'||Cget<'0') Cget=getchar();
        while(Cget>='0'&&Cget<='9')
        {
            now=now*10+Cget-'0';
            Cget=getchar();
        }
    }
    
    ll spfa(ll u,ll v)
    {
        ll dis[25],can[25],init[25],h=0,tail=1;
        for(ll i=1;i<=m;i++) can[i]=true,dis[i]=0x7ffffff,init[i]=false;
        for(ll i=u;i<=v;i++)
        {
            for(ll j=1;j<=m;j++) if(if_[i][j]) can[j]=false;
        }
        que[0]=1,dis[1]=0,init[1]=true;
        while(h<tail)
        {
            ll now=que[h++];init[now]=false;
            for(ll i=1;i<=m;i++)
            {
                if(can[i]&&dis[i]>dis[now]+map[now][i])
                {
                    dis[i]=dis[now]+map[now][i];
                    if(!init[i])
                    {
                        init[i]=true;
                        que[tail++]=i;
                    }
                }
            }
        }
        return dis[m];
    }
    
    int main()
    {
        in(n),in(m),in(k),in(e);ll u,v,w;
        memset(dp,127/3,sizeof(dp));
        memset(map,127/3,sizeof(map));
        while(e--)
        {
            in(u),in(v),in(w);
            map[u][v]=map[v][u]=min(w,map[v][u]);
        }
        in(e);
        while(e--)
        {
            in(w),in(u),in(v);
            for(ll i=u;i<=v;i++) if_[i][w]=true;
        }
        for(ll i=1;i<=n;i++)
        {
            for(ll j=i;j<=n;j++)
            {
                cost[i][j]=spfa(i,j);
            }
        }
        dp[0]=0;
        for(ll i=1;i<=n;i++)
        {
            for(ll j=0;j<i;j++)
            {
                dp[i]=min(dp[i],dp[j]+cost[j+1][i]*(i-j)+k);
            }
        }
        cout<<dp[n]-k;
    }
  • 相关阅读:
    算法70----只有两个键的键盘【动态规划】
    Shell
    Shell
    Shell
    Shell
    Shell
    Tools
    Jenkins
    Java
    Product
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6725070.html
Copyright © 2011-2022 走看看