bzoj1003 [ZJOI2006]物流運輸trans
阿新 • • 發佈:2019-02-09
本題為dp和最短路的結合,cost(X,Y) 表示從x到y時段的費用(注意最後時間是(Y-X+1), f [ i ] 表示到第i時段所需費用的最小值,dp方程:f[i]=min(f[i],f[j]+cost(j+1,i)+k) ;
/************************************************************** Problem: 1003 User: EOD_realize Language: C++ Result: Accepted Time:40 ms Memory:1480 kb ****************************************************************/ #include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <vector> #define INF 0x3f3f3f3f using namespace std; int n,m,k,e,num; const int maxn = 100 + 10; const int maxm = maxn * maxn; bool flag[maxn][maxn],done[maxn]; int dis[maxn],t[maxn],sum[maxn],f[maxn]; struct node { int v,dis; node(int x,int y) { v=x; dis=y; } }; int next[maxm],to[maxm],val[maxm],p[maxm]; void build(int x,int y,int w) { num++; to[num]=y; val[num]=w; next[num]=p[x]; p[x]=num; } int cost(int s,int t) { memset(dis,0x3f3f3f3f,sizeof(dis)); memset(done,false,sizeof(done)); for(int i=1;i<=m;i++) { for(int j=s;j<=t;j++) { if(!flag[i][j]) { done[i]=1; break; } } } queue<node>q; int flag,minn; dis[1]=0; q.push(node(1,0)); while(!q.empty()) { node now=q.front(); q.pop(); if(done[now.v]) continue; for(int i=p[now.v];i;i=next[i]) { if(done[to[i]]) continue; if(dis[to[i]]>dis[now.v]+val[i]) { dis[to[i]]=dis[now.v]+val[i]; q.push(node(to[i],dis[to[i]])); } } } if(dis[m]==INF) return INF; else return dis[m]*(t-s+1); } void readdata() { memset(flag,true,sizeof(flag)); scanf("%d%d%d%d",&n,&m,&k,&e); for(int i = 1;i <= e;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); build(x,y,z); build(y,x,z); } int d; scanf("%d",&d); for(int i = 1;i <= d;i++) { int p,a,b; scanf("%d%d%d",&p,&a,&b); for(int j = a;j <= b;j++) flag[p][j] = false; } } void solve() { for(int i=1;i<=n;i++) { f[i]=cost(1,i); for(int j=2;j<i;j++) { f[i]=min(f[i],f[j]+k+cost(j+1,i)); } } printf("%d\n",f[n]); } int main() { readdata(); solve(); return 0; }