这题。。写完了错了,找了快半小时,发现是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;
}