BZOJ 1003 物流运输

BZOJ 1003 物流运输

传送门
题解:
由因为天的数量的只有100,并且只有20个港口,数据量很小。因此,可以直接用最短路预处理第i天到第j天用同一种路径所需要的花费。然后,预处理之后,用一个简单的dp就可以了。\(dp[i]=min(dp[j]+cost[j+1][i]+k)\)其中\(dp[i]\)表示到第i天的最小花费,\(cost[i][j]\)第i天到第j天用同一种路径所需要的花费,k是换方案的费用。

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e4+50;
const int inf = 2e9;
long long cost[25];
long long c[105][105];
bool vis[25];
long long dp[105];
bool vis0[25][105];
bool flag[105];
struct node
{
    int id,dis;
    node(int x):id(x),dis(cost[x]){};
    bool operator<(const node& b)const
    {
        return dis<b.dis;
    }
};
struct edge
{
    int next,to,w;
}e[maxn];
int head[maxn*2],tot;
void add(int u,int v,int w)
{
    e[tot].to=v;
    e[tot].w=w;
    e[tot].next=head[u];
    head[u]=tot++;
}
void dijkstra(int n)
{
    //memset(vis,0,sizeof(vis));
    memset(cost,0x7f,sizeof(cost));
    cost[1]=0;
    priority_queue<node>Q;
    Q.push(node(1));
    while(!Q.empty())
    {
        node temp=Q.top();
        vis[temp.id]=1;
        Q.pop();
        for(int i=head[temp.id];i!=-1;i=e[i].next)
        {
            //if(vis[e[i].to]) continue;
            if(cost[temp.id]+e[i].w<cost[e[i].to]&&!flag[e[i].to])
            {
                cost[e[i].to]=cost[temp.id]+e[i].w;
                Q.push(node(e[i].to));
            }
        }
    }
}
int main()
{
    memset(head,-1,sizeof(head));
    int i,j,n,m,k,N,M;
    cin>>n>>m>>k>>N;
    int w,u,v;
    for(i=0;i<N;i++)
    {
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w);
        add(v,u,w);
    }
    cin>>M;
    for(i=0;i<M;i++)
    {
        scanf("%d%d%d",&w,&u,&v);
        for(j=u;j<=v;j++) vis0[w][j]=1;
    }
    for(i=1;i<=n;i++)
    {
        for(j=i;j<=n;j++)
        {
            memset(flag,0,sizeof(flag));
            for(int k=1;k<=m;k++)
            {
                for(int s=i;s<=j;s++)
                    flag[k]|=vis0[k][s];
            }
            dijkstra(m);
            //cout<<cost[m]<<endl;
            c[i][j]=cost[m];
        }
    }
    for(i=1;i<=n;i++)
        for(j=i;j<=n;j++)
            if(c[i][j]<inf) c[i][j]*=1ll*(j-i+1);
    memset(dp,0x7f,sizeof(dp));
    for(i=1;i<=n;i++) dp[i]=c[1][i];
    for(i=2;i<=n;i++)
    {
        for(j=1;j<i;j++)
        {
            dp[i]=min(dp[i],dp[j]+c[j+1][i]+k);
        }
    }
    cout<<dp[n]<<endl;
}

posted on 2018-11-02 21:51  TRZNDP_Z  阅读(87)  评论(0编辑  收藏  举报

导航