Original title Link: http://www.lydsy.com/JudgeOnline/problem.php?id=1003
Exercises
DP is good, so dp[i] represents the answer to the day I, then Dp[i]=min{cost (1,i), Cost (j+1,i) +dp[j]+k}, where cost (i,j) means the same scheme from I to J. This DP and partitioning problem is very similar.
Code:
#include <iostream>#include<cstring>#include<algorithm>#include<queue>#include<cstdio>#include<climits>#defineINF 0x3f3f3f3f#defineMax_m 220#defineMax_n 1110using namespacestd;intn,m,k,e;intDp[max_n];intD[max_m];queue<int>que;BOOLInque[max_m];structEdge { Public: intto, cost; Edge (intTintc): to (t), cost (c) {} edge () {}};vector<edge>G[max_m];BOOLUsed[max_m];vector<int>Days[max_n];intSPFA () { while(Que.size ()) Que.pop (); memset (Inque,0,sizeof(Inque)); Fill (d, D+ M +1, INF); Que.push (1); inque[1] =1; d[1] =0; while(Que.size ()) {intU =Que.front (); Que.pop (); Inque[u]=0; for(inti =0; I < g[u].size (); i++) { intv = g[u][i].to, C =G[u][i].cost; if(D[v] > D[u] + C && (!Used[v])) {D[v]= D[u] +C; if(!Inque[v]) {Inque[v]=1; Que.push (v); } } } } returnd[m];}intCost (intIintj) {memset (used,0,sizeof(used)); for(intK = i; K <= J; k++) for(intt =0; T < Days[k].size (); t++) Used[days[k][t]]=1; inttmp=SPFA (); if(Tmp==inf)returnINF; return(J-i +1) *tmp;}intMain () {//freopen ("1003.in", "R", stdin); //freopen ("1003.out", "w", stdout);scanf"%d%d%d%d", &n, &m, &k, &E); for(inti =0; i < E; i++) { intu, V, c; scanf ("%d%d%d", &u, &v, &B); G[u].push_back (Edge (V, c)); G[v].push_back (Edge (U, c)); } intD; scanf ("%d",&D); while(d--) { intP, A, B; scanf ("%d%d%d", &p, &a, &b); for(inti = A; I <= b; i++) Days[i].push_back (P); } for(inti =1; I <= N; i++) {Dp[i]= Cost (1, i); for(intj =1; J < I; J + +) Dp[i]= Min (Dp[i], cost (j +1, i) + dp[j] +K); } printf ("%d\n", Dp[n]); return 0;}
Bzoj 1003: [ZJOI2006] Logistics transportation Trans SPFA+DP