BZOJ 1003 物流运输

最短路+dp。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define maxd 150
#define maxv 250
#define maxe 50050
#define inf 1000000007
using namespace std;
struct edge
{
    long long v,w,nxt;
}e[maxe];
long long d,n,k,m,qq,g[maxv],nume=0,dis[maxv],dp[maxv],x,y,z,t[maxd][maxd];
bool lim[maxd][maxv],vis[maxv],block[maxv];
queue <long long> q;
void addedge(long long u,long long v,long long w)
{
    e[++nume].v=v;
    e[nume].w=w;
    e[nume].nxt=g[u];
    g[u]=nume;
}
void reset(long long x,long long y)
{
    memset(block,true,sizeof(block));
    fill(dis+1,dis+n+1,inf);
    memset(vis,false,sizeof(vis));
    while (!q.empty()) q.pop();
    for (long long i=x;i<=y;i++)
        for (long long j=1;j<=n;j++)
        {
            if (!lim[i][j])
                block[j]=false;
        }
}
long long spfa(long long x,long long y)
{
    reset(x,y);
    q.push(1);dis[1]=0;vis[1]=true;
    while (!q.empty())
    {
        long long head=q.front();q.pop();
        for (long long i=g[head];i;i=e[i].nxt)
        {
            long long v=e[i].v;
            if ((block[v]) && (dis[v]>dis[head]+e[i].w))
            {
                dis[v]=dis[head]+e[i].w;
                if (!vis[v])
                {
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
        vis[head]=false;
    }
    return dis[n];
}
void dpp()
{
    for (long long i=1;i<=d;i++)
    {
        dp[i]=t[1][i]*i;
        for (long long j=0;j<i;j++)
            dp[i]=min(dp[i],dp[j]+k+(i-j)*t[j+1][i]);
    }
}
int main()
{
    memset(g,0,sizeof(g));
    memset(lim,true,sizeof(lim));
    scanf("%lld%lld%lld%lld",&d,&n,&k,&m);
    for (long long i=1;i<=m;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        addedge(x,y,z);
        addedge(y,x,z);
    }
    scanf("%lld",&qq);
    for (long long i=1;i<=qq;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        for (long long j=y;j<=z;j++)
            lim[j][x]=false;    
    }
    for (long long i=1;i<=d;i++)
        for (long long j=i;j<=d;j++)
            t[i][j]=spfa(i,j);
    dpp();
    printf("%lld
",dp[d]);
    return 0;
}
原文地址:https://www.cnblogs.com/ziliuziliu/p/5694954.html