bzoj 1003 logistics transportation (pretreatment shortest path + interval dp)

Keywords: Programming

Question meaning: Give a picture, let you run n shortest paths, the first shortest paths have a number of points can not be used, and change a route will need to add k additional costs, ask after running n minimum costs.

Train of Thought: The starting point is that the cost is unchanged in a certain period of time, changing the route will cost more, and naturally think of dp. So when we think of dividing the n-th shortest path into the sum of the shortest paths in several intervals, we can pretreat each shortest path, because only the n*n interval has a maximum of 100. Let dp[i][j] denote the minimum of all costs for the shortest paths from the first to the third. So the answer is dp[1][n].

Interval dp is the way to write a routine. The first dimension enumerates the length of the interval, the second dimension enumerates the starting point, and the third dimension enumerates the middle point.

The shortest path in a preprocessing period is to check whether a point is available before adding relaxation.

(n and m are silly and confused, wa a few more)

#include<bits/stdc++.h>
using namespace std;
const int maxn=200;
const int maxm=1000;
int cnt=-1,n,m,k,e;
int head[maxn],use[110][110],dist[maxn],dp[110][110];
bool inq[maxn];
struct Edge
{
    int nex;
    int to,w;
} edge[maxm];

void add_edge(int u,int v,int w)
{
    edge[++cnt].nex=head[u];
    edge[cnt].to=v;
    edge[cnt].w=w;
    head[u]=cnt;
}
bool check(int x,int s,int t)
{
    for(int i=s; i<=t; i++)
        if(!use[x][i]) return false;
    return true;
}
int spfa(int s,int t)
{
    memset(dist,0x3f,sizeof(dist));
    memset(inq,false,sizeof(inq));
    queue<int>que;
    while(!que.empty()) que.pop();
    que.push(1);
    dist[1]=0;
    inq[1]=true;
    while(!que.empty())
    {
        int u=que.front();
        que.pop();
        inq[u]=false;
        for(int i=head[u]; i!=-1; i=edge[i].nex)
        {
            int v=edge[i].to;
            if(check(v,s,t)&&dist[v]>dist[u]+edge[i].w)
            {
                dist[v]=dist[u]+edge[i].w;
                if(!inq[v])
                    inq[v]=true,que.push(v);
            }
        }
    }
    return dist[m]==0x3f3f3f3f ? 0x3f3f3f3f:dist[m]*(t-s+1);
}
void solve()
{
    for(int i=1; i<=n; i++)
    {
        for(int j=i; j<=n; j++)
            dp[i][j]=spfa(i,j);
    }
    int e;
    for(int len=2; len<=n; len++)
        for(int s=1; (e=s+len-1)<=n; s++)
            for(int p=s; p<s+len-1; p++)
            {
                dp[s][e]=min(dp[s][e],dp[s][p]+dp[p+1][e]+k);
            }
    printf("%d\n",dp[1][n]);
}

int main()
{
    while(~scanf("%d %d %d %d",&n,&m,&k,&e))
    {
        memset(head,-1,sizeof(head));
        cnt=-1;
        for(int i=1;i<maxm;i++)
            edge[i].nex=-1;
        for(int i=1; i<=e; i++)
        {
            int a,b,c;
            scanf("%d %d %d",&a,&b,&c);
            add_edge(a,b,c);
            add_edge(b,a,c);
        }
        memset(use,1,sizeof(use));
        int tem;
        scanf("%d",&tem);
        for(int i=1; i<=tem; i++)
        {
            int p,a,b;
            scanf("%d %d %d",&p,&a,&b);
            for(int j=a; j<=b; j++)
                use[p][j]=0;
        }
        solve();
    }
}

 

 

 

Posted by webosb on Fri, 01 Feb 2019 22:39:15 -0800