[BZOJ 1003][ZJOI2006]物流运输:DP+SPFA

来源:互联网 发布:sublimetext mac 破解 编辑:程序博客网 时间:2024/05/21 15:56

点击这里查看原题

c[i][j]表示i-j天走同一航线的最小花费,用SPFA处理。
于是得到方程:f[i]=min{f[j]+c[j+1][i]+k},最后结果为f[n]-k。
注意千万不要把n,m打反,我因为把最后结果打为f[m]-k,WA了3次

/*User:SmallLanguage:C++Problem No.:1003*/#include<bits/stdc++.h>#define ll long long#define inf 999999999using namespace std;int n,m,k,ee,f[105],c[105][105],fir[25],tot,d;bool ban[25][105],vis[25];struct edge{    int v,w,nex;}e[10005];void add(int u,int v,int w){    e[++tot]=(edge){v,w,fir[u]};    fir[u]=tot;}void spfa(int st,int ed){    bool un[25];    int dis[25];    memset(un,0,sizeof(un));    memset(dis,127,sizeof(dis));    for(int i=2;i<m;i++){        for(int j=st;j<=ed;j++){            if(ban[i][j]){                un[i]=1;                break;            }        }    }    queue<int> q;    q.push(1);    vis[1]=1;    dis[1]=0;    while(!q.empty()){        int u=q.front();        q.pop();        vis[u]=0;        for(int i=fir[u];i;i=e[i].nex){            int v=e[i].v;            if(un[v]) continue;            if(dis[u]+e[i].w<dis[v]){                dis[v]=dis[u]+e[i].w;                if(!vis[v]){                    vis[v]=1;                    q.push(v);                }            }        }    }    if(dis[m]<inf) c[st][ed]=dis[m]*(ed-st+1);}int main(){    freopen("data.in","r",stdin);//    scanf("%d%d%d%d",&n,&m,&k,&ee);    while(ee--){        int x,y,w;        scanf("%d%d%d",&x,&y,&w);        add(x,y,w);        add(y,x,w);    }    scanf("%d",&d);    while(d--){        int p,a,b;        scanf("%d%d%d",&p,&a,&b);        for(int i=a;i<=b;i++) ban[p][i]=1;    }    memset(c,127,sizeof(c));    for(int i=1;i<=n;i++)        for(int j=i;j<=n;j++)            spfa(i,j);    for(int i=1;i<=n;i++){        f[i]=inf;        for(int j=0;j<i;j++)            if(c[j+1][i]<inf) f[i]=min(f[i],f[j]+c[j+1][i]+k);    }    printf("%d\n",f[n]-k);    return 0;}
0 0
原创粉丝点击