bzoj1003: [ZJOI2006]物流运输
dp.
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 100 + 10; const int maxm = 2000 + 10; const int maxv = 20 + 10; const int INF = 0x3f3f3f3f; int g[maxn],v[maxm],next[maxm],d[maxm],eid; bool able[maxv][maxn]; int n,m,k,e,h; int q[10010],l,r; int dist[maxn],inque[maxn]; int f[maxn][maxn]; void addedge(int a,int b,int c) { v[eid]=b; next[eid]=g[a]; d[eid]=c; g[a]=eid++; v[eid]=a; next[eid]=g[b]; d[eid]=c; g[b]=eid++; } void build() { memset(g,-1,sizeof(g)); memset(able,1,sizeof(able)); scanf("%d%d%d%d",&n,&m,&k,&e); for(int i=1,u,v,w;i<=e;i++) { scanf("%d%d%d",&u,&v,&w); addedge(u,v,w); } scanf("%d",&h); for(int i=1,p,a,b;i<=h;i++) { scanf("%d%d%d",&p,&a,&b); for(int j=a;j<=b;j++) able[p][j]=0; } } bool ok(int a,int u,int v) { for(int i=u;i<=v;i++) if(!able[a][i]) return false; return true; } int spfa(int from,int to) { memset(dist,0x3f,sizeof(dist)); memset(inque,0,sizeof(inque)); l=r=0; q[r++]=1; dist[1]=0; while(l<r) { int u=q[l++]; inque[u]=0; for(int i=g[u];~i;i=next[i]) if(ok(v[i],from,to) && dist[v[i]]>dist[u]+d[i]) { dist[v[i]]=dist[u]+d[i]; if(!inque[v[i]]) inque[q[r++]=v[i]]=1; } } return (dist[m]==INF ? INF : dist[m]*(to-from+1)); } void solve() { for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) f[i][j]=spfa(i,j); for(int len=2,e;len<=n;len++) for(int s=1;(e=s+len-1)<=n;s++) for(int q=s;q<e;q++) f[s][e]=min(f[s][e],f[s][q]+k+f[q+1][e]); printf("%d\n",f[1][n]); } int main() { build(); solve(); return 0; }