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;
    }
  • 相关阅读:
    [OpenGL ES 071]光照原理
    [OpenGL ES 03]3D变换:模型,视图,投影与Viewport
    [日志]当今最流行的网络生僻字,很火
    [日志]关于茶的基础知识
    [健康]快速除牙痛的八个小验方
    [日志]我们生活中的潜规则
    [日志]做事要方,做人要圆
    [日志]家居装修花钱看你怎么省
    [日志]非常宝贵的工作经验
    [日志]你用的着的一些家装尺寸数据
  • 原文地址:https://www.cnblogs.com/sbfhy/p/6412166.html
Copyright © 2011-2022 走看看