zoukankan      html  css  js  c++  java
  • BZOJ 1003 dp+最短路

    1003: [ZJOI2006]物流运输

    题意:m个码头,从码头1到码头m,连续n天都要运送货物。每一天的花费是总路线长度大小,但如果和前一天的路线不一样,要另处加上k元花费。而且有些码头有些天不能用,问这n天的最小费用。

    tags:菜鸡一开始真没想到是dp

    求n天时最小花费,就要想到以天数为阶段进行规划。dp[i][j]表示第i天到第j天走同一条路线的花费,则f[i]=min( f[i], f[j]+dp[j+1][i]+k )。

    #include<bits/stdc++.h>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define FF(i,a,b) for (int i=a;i<=b;i++)
    #define F(i,b,a)  for (int i=b;i>=a;i--)
    #define mes(a,b)  memset(a,b,sizeof(a))
    #define INF 0x3f3f3f3f
    typedef long long ll;
    const int N = 200;
    const ll inf=1e18;
    
    int n, m, k, e1, d1, q[10000], head[N], tot;
    ll c[N][N], dis[N], f[N];
    bool vis[N], use[N], flag[N][N];
    struct Edge{int to, next; ll w;}e[N*N];
    void Addedge(int u, int v, ll w) { e[++tot].to=v, e[tot].w=w, e[tot].next=head[u], head[u]=tot; };
    ll spfa(int x, int y)
    {
        mes(use, 0);  mes(vis, 0);
        FF(i,1,m) dis[i]=inf;   dis[1]=0;
        FF(i,x,y) FF(j,1,m) if(flag[j][i]) use[j]=1;
        int t=0, h=0;
        q[++t]=1, dis[1]=0;
        while(h!=t) {
            int u=q[++h]; vis[u]=1;
            for(int i=head[u]; i; i=e[i].next) {
                int v=e[i].to;  ll w=e[i].w;
                if(use[v]==0 && dis[v]>dis[u]+w) {
                    dis[v]=dis[u]+w;
                    if(vis[v]==0) q[++t]=v, vis[v]=1;
                }
            }
            vis[u]=0;
        }
        return dis[m]*(dis[m]>=inf ? 1 : (y-x+1));
    }
    void Init()
    {
        scanf("%d %d %d %d", &n, &m, &k, &e1);
        int u, v, p, a, b;
        ll w;
        FF(i,1,e1) {
            scanf("%d %d %lld", &u, &v, &w);
            Addedge(u, v, w);  Addedge(v, u, w);
        }
        scanf("%d", &d1);
        FF(i,1,d1) {
            scanf("%d %d %d", &p, &a, &b);
            FF(j,a,b) flag[p][j]=1;
        }
        FF(i,1,n) FF(j,1,i) c[j][i]=spfa(j, i);
    }
    void DP()
    {
        FF(i,1,n) {
            f[i]=c[1][i];
            FF(j,1,i-1) f[i]=min(f[i], f[j]+c[j+1][i]+k);
        }
        printf("%lld
    ", f[n]);
    }
    int main()
    {
        //freopen("in.txt", "r", stdin);
        Init();
        DP();
    
        return 0;
    }
  • 相关阅读:
    第四章JAVA EE基础知识
    第二章代码审计环境搭建
    第三章代码审计辅助工具简介
    python json.dumps 中文需要注意的事项
    multiprocessing 使用实践
    Python中*args和**kwargs的使用实践
    python 继承学习记录
    关于vue-element-admin启动项目遇到的一些问题
    @RequestParam
    前端菜单点击切换样式,菜单控制iframe
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6412166.html
Copyright © 2011-2022 走看看