网络流24题之T10 餐巾计划问题

这题。。写完了错了,找了快半小时,发现是inq和q搞差了,还有丢了一个p数组。。

#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <cstring>
using namespace std ;
const int oo=1000000000;
const int maxn=2010;

typedef struct EDGE{
    int front,next;
    int cap,flow;
    int cost;
}E;
E edge[25010];
int len=-1;
struct READIN {
    int p,f,n,m,s;
}R;
int n,s,t,tot;
int head[maxn],next[25010];
int q[maxn],inq[maxn];
int dist[maxn],p[maxn],a[maxn];
int S,T,allp;
void E_add (int s,int t,int c,int f){
    edge[++len].front=s;
    edge[len].next=t;
    edge[len].cap=c;
    edge[len].cost=f;
    next[len]=head[s];
    head[s]=len;
    edge[++len].front=t;
    edge[len].next=s;
    edge[len].cost=-f;
    next[len]=head[t];
    head[t]=len;
}
void init (){
    freopen ("prog810.in","r",stdin);
    freopen ("prog810.out","w",stdout);
    scanf ("%d %d %d %d %d %d",&n,&R.p,&R.m,&R.f,&R.n,&R.s);
    memset (head,-1,sizeof(head));
    S=0;
    T=2*n+1;
    allp=T;
    int i,j;
    for (i=1;i<=n;i++){
        scanf ("%d",&j);
        E_add (S,i,j,0);
        E_add (i+n,T,j,0);
        E_add (S,i+n,oo,R.p);
        if (i+1<=n) E_add (i,i+1,oo,0);
        if (i+R.m<=n) E_add (i,i+n+R.m,oo,R.f);
        if (i+R.n<=n) E_add (i,i+n+R.n,oo,R.s);
    }
}
bool spfa (int &flow,int &cost){
    int heads=0,tail=0;
    int now,i;
    for (i=0;i<=allp;i++) dist[i]=oo;
    memset (inq,0,sizeof(inq));
    dist[S]=0; inq[S]=1;p[S]=0;a[S]=oo;
    q[tail++]=S;
    while (heads!=tail){
        now=q[heads++];
        if (heads==2000) heads=0;
        inq[now]=0;
        for (i=head[now];i>=0;i=next[i]){
            E &e=edge[i];
            if (e.cap>e.flow&&dist[e.next]>dist[now]+e.cost){
                dist[e.next]=dist[now]+e.cost;
                p[e.next]=i;
                a[e.next]=min (a[now],e.cap-e.flow);
                if (!inq[e.next]){
                    q[tail++]=e.next;
                    if (tail==2000) tail=0;
                    inq[e.next]=1;
                }
            }
        }
    }
    if (dist[T]==oo) return false;
    flow+=a[T];
    cost+=dist[T]*a[T];
    now=T;
    while (now!=S){
        edge[p[now]].flow+=a[T];
        edge[p[now]^1].flow-=a[T];
        now=edge[p[now]].front;
    }
    return true;
}
void work (){
    int flow=0,cost=0;
    while (spfa (flow,cost));
    printf ("%d\n",cost);
}
int main (){
    init ();
    work ();
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值