【网络流】【BZOJ1221】【HNOI2001】软件开发

原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1221

题意:你有3种方法进行对毛巾的处理,不同的处理方法有不同的cost,问你要如何规划才可以使得总花费最低。

解题思路:我们对每个点进行拆点,分为用过的毛巾和没用过的,这样就可以较为简单的连边,然后跑个最小费用最大流即可。

AC代码:

#include<stdio.h>
#include<string.h>
#define inf 0x7fffffff
#define min(a,b) (a<b?a:b)
struct zxy{int to,next,c,v;}edge[40100];
int n,e,cnt=1,head[2005],dis[2005],que[10001],pre[2005],fc,ta,tb,fa,fb;
bool vis[2005];
inline int in(){
    int x=0;
    char ch=getchar();
    while(ch<'0'||ch>'9') ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x;
}
inline void ins(int x,int y,int v,int l){
    edge[++cnt].to=y,edge[cnt].next=head[x],edge[cnt].v=v,edge[cnt].c=l,head[x]=cnt;
    edge[++cnt].to=x,edge[cnt].next=head[y],edge[cnt].v=0,edge[cnt].c=l*(-1),head[y]=cnt;
}
inline bool SPFA(int s,int e){
    for (register int i=s; i<=e; ++i) dis[i]=inf/3;
    int h=0,t=1;
    que[1]=s;
    dis[s]=0;vis[s]=1;
    do{
        int w=que[++h];
        for (register int i=head[w]; i; i=edge[i].next)
            if (dis[w]+edge[i].c<dis[edge[i].to]&&edge[i].v){
                int v=edge[i].to;pre[v]=i;
                dis[v]=dis[w]+edge[i].c;
                if (!vis[v]){
                    vis[v]=1;
                    if (dis[v]<dis[que[h+1]])que[h--]=v;
                    else que[++t]=v;
                }
            }
        vis[w]=0;
    }while(h<t);
    return dis[e]!=inf/3;
}
int cost_flow(int s,int t){
    int cost=0;
    while(SPFA(s,t)){
        int mi=inf;
        for (register int i=t; i; i=edge[pre[i]^1].to)
            mi=min(mi,edge[pre[i]].v);
        for (register int i=t; i; i=edge[pre[i]^1].to)
            edge[pre[i]].v-=mi,edge[pre[i]^1].v+=mi;
        cost+=dis[t]*mi;
    }
    return cost;
}
void init(){
    n=in(),ta=in(),tb=in(),fc=in(),fa=in(),fb=in();
    for (int i=1; i<=n; ++i){
        register int x=in();
        ins(0,n+i,inf,fc);
        ins(0,i,x,0);
        ins(n+i,2*n+1,x,0);
        if(i<n) ins(i,i+1,inf,0);
        if(i+ta<n) ins(i,i+ta+n+1,inf,fa);
        if(i+tb<n) ins(i,i+tb+n+1,inf,fb);
    }
}
int main(){
    init();
    printf("%d",cost_flow(0,2*n+1));
}

 

posted @ 2017-03-22 17:12  Melacau  阅读(167)  评论(0编辑  收藏  举报