bzoj1003 物流运输

传送门

分析

设dp[i]为进行i轮的最小值

所以不难得出dp[i]=Min(dp[i],dp[j-1]+(i-j+1)*dij(j,i)+k)

dij(L,R)表示在[L,R]这几天的最小值

处理这几天哪些点不能走然后求最短路即可

注意dp[0]=-k

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<long long,long long>
const long long inf = 0x3f3f3f3f;
long long n,m,e,t,d[110],dp[110],is[30],vis[110];
long long col[10010],le[10010],ri[10010];
vector<pii>v[110];
priority_queue<pii>q;
inline long long dij(long long L,long long R){
    long long i,j,k;
    for(i=1;i<=m;i++)is[i]=1;
    for(i=1;i<=t;i++)
      if((le[i]>=L&&le[i]<=R)||(ri[i]>=L&&ri[i]<=R)
        ||(le[i]<=L&&ri[i]>=R))is[col[i]]=0;
    memset(d,0x3f,sizeof(d));
    memset(vis,0,sizeof(vis));
    d[1]=0;
    q.push(mp(0,1));
    while(!q.empty()){
      long long x=q.top().se;
      q.pop();
      if(vis[x])continue;
      vis[x]=1;
      for(i=0;i<v[x].size();i++){
          long long y=v[x][i].fi,z=v[x][i].se;
          if(!is[y])continue;
          if(d[y]>d[x]+z){
            d[y]=d[x]+z;
            q.push(mp(-d[y],y));
          }
      }
    }
    return d[m];
}
int main(){
    long long i,j,k;
    scanf("%lld%lld%lld%lld",&n,&m,&k,&e);
    for(i=1;i<=e;i++){
      long long x,y,z;
      scanf("%lld%lld%lld",&x,&y,&z);
      v[x].pb(mp(y,z));
      v[y].pb(mp(x,z));
    }
    scanf("%lld",&t);
    for(i=1;i<=t;i++)
      scanf("%lld%lld%lld",&col[i],&le[i],&ri[i]);
    memset(dp,0x3f,sizeof(dp));
    dp[0]=-k;
    for(i=1;i<=n;i++)
      for(j=i;j>0;j--){
          long long x=dij(j,i);
          if(x>=inf)break;
        dp[i]=min(dp[i],dp[j-1]+(i-j+1)*x+k);
      }
    printf("%lld\n",dp[n]);
    return 0;
}
posted @ 2018-11-17 20:22  水题收割者  阅读(148)  评论(0编辑  收藏  举报