zoukankan      html  css  js  c++  java
  • BZOJ 1003 [ZJOI2006]物流运输trans SPFA+DP

    题意:链接

    方法:SPFA+DP

    解析:挺好的题目。因为数据范围较小所以用这样的方式能够搞,只是也是挺不好想的。

    我们定义cost(i,j)表示从第i天走到第j天运用同一种方式的最小花费,然后因为数据比較小,我们定义f[i]表示前i天的最小花费。

    接下来我们就能够写出来转移方程了

    f[i]=minf[i],f[j]+K+cost(j+1,i)

    j比i小。

    然后就能够水过了!

    顺带提一下,在计算cost(j+1,i)时,要考虑每一个限制区段的预处理,也就是哪些点在这些天中均可走。

    代码

    #include <queue> 
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 110
    #define M 10100
    #define INF 0x3f3f3f3f
    using namespace std;
    int n,m,K,e,d,cnt;
    int v[N],can[N],f[N];
    struct node
    {
        int to;
        int next;
        int val;
    }edge[M];
    int head[N],dis[N];
    struct limit
    {
        int p,a,b;
    }l[M];
    //f[i]=max(c(1,i),f[j]+k+c(j+1,i));
    void init()
    {
        memset(head,-1,sizeof(head));
        cnt=1;
    }
    void edgeadd(int from,int to,int val)
    {
        edge[cnt].to=to;
        edge[cnt].val=val;
        edge[cnt].next=head[from];
        head[from]=cnt++;
    }
    int cost(int le,int ri)
    {
        memset(can,0,sizeof(can));
        for(int i=1;i<=d;i++)
        {
            if(max(le,l[i].a)<=min(ri,l[i].b))can[l[i].p]=1;
        }
        memset(dis,0x3f,sizeof(dis));
        memset(v,0,sizeof(v));
        queue<int>q;
        q.push(1);
        v[1]=1;
        dis[1]=0;
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            v[u]=0;
            for(int i=head[u];i!=-1;i=edge[i].next)
            {
                int to=edge[i].to;
                if(can[to])continue;
                if(dis[u]+edge[i].val<dis[to])
                {
                    dis[to]=dis[u]+edge[i].val;
                    if(!v[to])
                    {
                        q.push(to);
                        v[to]=1;
                    }
                }
            }
        }
        if(dis[m]==INF)return INF;
        return dis[m]*(ri-le+1);
    }
    int main()
    {
        init();
        scanf("%d%d%d%d",&n,&m,&K,&e);
        for(int i=1;i<=e;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            edgeadd(x,y,z);
            edgeadd(y,x,z);
        }
        scanf("%d",&d);
        for(int i=1;i<=d;i++)scanf("%d%d%d",&l[i].p,&l[i].a,&l[i].b);
        for(int i=1;i<=n;i++)
        {
            f[i]=cost(1,i);
            for(int j=1;j<i;j++)
            {
                f[i]=min(f[i],f[j]+K+cost(j+1,i));
            }
        }
        printf("%d
    ",f[n]);
    }
  • 相关阅读:
    随时积累随手记(持续更新...)
    Zookeeper集群搭建
    Dubbo——基于Zookeeper服务框架搭建及案例演示
    nginx配置浅析
    阿里面试回来,想和Java程序员谈一谈
    博客收藏列表
    启示录:打造用户喜爱的产品
    js深拷贝和浅拷贝
    MyBatis 总结记录
    ActiveMQ初体验
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7048442.html
Copyright © 2011-2022 走看看