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;
}