zoukankan      html  css  js  c++  java
  • 【BZOJ1003】物流运输(ZJOI2006)-DP+最短路

    测试地址:物流运输
    做法:本题需要用到DP+最短路。
    容易想到,我们可以把这些天分成若干个区间,每个区间使用同一条运输路线,最优的运输路线当然就是不经过任何这几天中禁入的码头的最短路线,然后就是一个裸的区间型DP了,注意特判从一开始就使用同一条路线的情况即可。总的时间复杂度为O(n2m2)
    以下是本人代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define inf 2000000000
    using namespace std;
    int n,m,k,e,d,f[110],dis[25],g[25][25];
    int forbid[110][25]={0},forb[25];
    bool vis[25];
    
    void dijkstra()
    {
        memset(vis,0,sizeof(vis));
        for(int i=1;i<=m;i++) dis[i]=inf;
        dis[1]=0;vis[1]=1;
        for(int i=1;i<=m;i++)
            if (g[1][i]!=-1&&!forb[i]) dis[i]=g[1][i];
        for(int i=1;i<m;i++)
        {
            int v=-1,mn=inf;
            for(int i=1;i<=m;i++)
                if (!vis[i]&&dis[i]<mn) mn=dis[i],v=i;
            if (v==-1) break;
            vis[v]=1;
            for(int i=1;i<=m;i++)
                if (g[v][i]!=-1&&!forb[i]) dis[i]=min(dis[i],dis[v]+g[v][i]);
        }
    }
    
    int main()
    {
        scanf("%d%d%d%d",&n,&m,&k,&e);
        for(int i=1;i<=m;i++)
            for(int j=1;j<=m;j++)
                g[i][j]=-1;
        for(int i=1;i<=e;i++)
        {
            int a,b,d;
            scanf("%d%d%d",&a,&b,&d);
            if (g[a][b]==-1) g[a][b]=g[b][a]=d;
            else g[a][b]=g[b][a]=min(g[a][b],d);
        }
        scanf("%d",&d);
        for(int i=1;i<=d;i++)
        {
            int p,a,b;
            scanf("%d%d%d",&p,&a,&b);
            forbid[a][p]++,forbid[b+1][p]--;
        }
        for(int i=2;i<=n;i++)
            for(int j=1;j<=m;j++)
                forbid[i][j]+=forbid[i-1][j];
    
        f[0]=0;
        for(int i=1;i<=n;i++)
        {
            f[i]=inf;
            for(int j=1;j<=m;j++) forb[j]=0;
            for(int j=i;j>=2;j--)
            {
                for(int l=1;l<=m;l++)
                    forb[l]+=forbid[j][l];
                dijkstra();
                if (dis[m]==inf) break;
                f[i]=min(f[i],f[j-1]+(i-j+1)*dis[m]+k);
            }
            if (dis[m]!=inf)
            {
                for(int j=1;j<=m;j++)
                    forb[j]+=forbid[1][j];
                dijkstra();
                if (dis[m]!=inf) f[i]=min(f[i],i*dis[m]);
            }
        }
    
        printf("%d",f[n]);
    
        return 0;
    }
  • 相关阅读:
    SQL 视图 局部变量 全局变量 条件语句 事务 触发器
    asp.net中的cookie
    Ajax 学习笔记
    接口与抽象类
    log4net日志组件
    StringBulider简单用法
    Web.Config文件详解
    性能优化之无阻塞加载脚步方法比较
    vue双向数据绑定原理探究(附demo)
    让你的JS更优雅的小技巧
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793550.html
Copyright © 2011-2022 走看看