1003: [ZJOI2006]物流运输

Posted acm1ruoji

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1003: [ZJOI2006]物流运输相关的知识,希望对你有一定的参考价值。

题目链接:

题意:给出n天,m个点,e条边,k是一个改变航线用的花费

然后给出e条边的信息,有u v w,分别为u到v的长度是w

然后给出T组输入

也是三个值,x,l,r表示x港口在l到r天都不能使用

每天都要从港口1运东西到港口m,问n天的最小花费(修改航道要花费k)

solve:

设f[i]为i天的最小花费

那么就有f[i]=min(f[i],f[j]+(i-j)*dij(j+1,i)+k)这样的递推式

用f[j]的加上j+1天到i天的最短路径 *天数 +k,枚举这些值找最小的就是i天的最小花费

 

不知道有没有人有疑问为什么每次都要加k,不会存在f[j]跟dij(j+1,i)的路线相同吗?  确实的确存在,那为什么要加k?因为如果存在这种情况,那么肯定是前面某个j已经算过了,那么后面更新的+k是不可能小于前面那个值的

所以任意时候加k对答案的最小值没有影响!!!

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <iostream>
using namespace std;
#define ll long long
#define fi first
#define se second
#define re register
#define pb push_back
void read(int &a)
{
    a=0;
    int d=1;
    char ch;
    while(ch=getchar(),ch>9||ch<0)
        if(ch==-)
            d=-1;
    a=ch-0;
    while(ch=getchar(),ch>=0&&ch<=9)
        a=a*10+ch-0;
    a*=d;
}
void write(int x)
{
    if(x<0)
        putchar(45),x=-x;
    if(x>9)
        write(x/10);
    putchar(x%10+0);
}
ll f[105];
int a[30][30],dis[105];
int n,m,k,e;
bool cnt[30][105],vis[30],book[30];
struct note
{
    int dis,pos;
    bool operator < (const note &x) const
    {
        return x.dis<dis;
    }
};
ll solve(int l,int r)
{
    memset(vis,0,sizeof(vis));
    memset(dis,0x3f,sizeof(dis));
    dis[1]=0;
    priority_queue <note> q;
    q.push({0,1});
    for(re int i=1;i<=m;i++)
        for(re int j=l;j<=r;j++)
            vis[i]|=cnt[i][j];
    while(!q.empty())
    {
        note p=q.top();q.pop();
        if(vis[p.pos]) continue;
        vis[p.pos]=1;
        for(re int i=1;i<=m;i++)
        {
            if(vis[i]) continue;
            if(dis[i]>dis[p.pos]+a[p.pos][i])
            {
                dis[i]=dis[p.pos]+a[p.pos][i];
                if(!vis[i]) q.push({dis[i],i});
            }
        }
    }
    return 1ll*(r-l+1)*dis[m];
}
int main()
{
    read(n),read(m),read(k),read(e);
    memset(a,0x3f,sizeof(a));
    for(re int i=1;i<=e;i++)
    {
        int u,v,w;
        read(u),read(v),read(w);
        a[u][v]=min(a[u][v],w);
        a[v][u]=min(a[v][u],w);
    }
    int T;read(T);
    while(T--)
    {
        int x,l,r;
        read(x),read(l),read(r);
        for(re int i=l;i<=r;i++) cnt[x][i]=true;
    }
    for(re int i=1;i<=n;i++)
    {
        f[i]=solve(1,i);
        for(re int j=2;j<i;j++) f[i]=min(f[i],f[j]+solve(j+1,i)+k);
    }
    printf("%lld
",f[n]);
    return 0;
}

 

以上是关于1003: [ZJOI2006]物流运输的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1003[ZJOI2006]物流运输

「bzoj1003」「ZJOI2006」物流运输 最短路+区间dp

BZOJ 1003: [ZJOI2006]物流运输

bzoj 1003: [ZJOI2006]物流运输

BZOJ-1003: [ZJOI2006]物流运输(SPFA+DP)

BZOJ 1003: [ZJOI2006]物流运输