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;
}
posted @ 2016-05-17 00:24  invoid  阅读(174)  评论(0编辑  收藏  举报