BZOJ 1221: [HNOI2001] 软件开发|费用流

来源:互联网 发布:jquery ajax 返回json 编辑:程序博客网 时间:2024/05/16 06:57

把每天分为二分图两个集合中的顶点Xi,Yi,建立附加源S汇T。

1、从S向每个Xi连一条容量为ri,费用为0的有向边。

2、从每个Yi向T连一条容量为ri,费用为0的有向边。

3、从S向每个Yi连一条容量为无穷大,费用为p的有向边。

4、从每个Xi向Xi+1(i+1<=N)连一条容量为无穷大,费用为0的有向边。

5、从每个Xi向Yi+m+1(i+m+1<=N)连一条容量为无穷大,费用为f的有向边。

6、从每个Xi向Yi+n+1(i+n+1<=N)连一条容量为无穷大,费用为s的有向边。

求网络最小费用最大流,费用流值就是要求的最小总花费。

感觉费用流好神奇

#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<set>#include<map>#include<algorithm>#include<iostream>#define MX 200000000using namespace std;int sc(){    int i=0; char c=getchar();    while(c>'9'||c<'0')c=getchar();    while(c>='0'&&c<='9')i=i*10+c-'0',c=getchar();    return i;}bool inq[2222];int dis[2222],q[2222],from[2222],p[2222];int head[2222],lst[55555],nxt[55555],c[55555],v[55555];int n,a,b,fa,f,fb,tot=1;int S,T,ans;void add(int x,int y,int a,int b){    lst[++tot]=y;    c[tot]=a;    v[tot]=b;    nxt[tot]=head[x];    head[x]=tot;}void insert(int a,int b,int c,int d){add(a,b,c,d);add(b,a,0,-d);}bool spfa(){    for(int i=1; i<=T; i++) dis[i]=MX; dis[S]=0;    int l=1,r=2; q[1]=S;    while(l!=r)    {        int x=q[l++];l%=2200;inq[x]=0;        for(int i=head[x];i;i=nxt[i])            if(c[i]&&dis[x]+v[i]<dis[lst[i]])            {                dis[lst[i]]=dis[x]+v[i];                from[lst[i]]=x;p[lst[i]]=i;                if(!inq[lst[i]])q[r++]=lst[i],r%=2200,inq[lst[i]]=1;            }    }    //cout << dis[T]<<" "<< ans << endl;    return dis[T]!=MX;}void mcf(){    int cc=MX,vv=0;    for(int i=T;i!=S;i=from[i]) cc=min(cc,c[p[i]]);    for(int i=T;i!=S;i=from[i])    {        c[p[i]]-=cc,c[p[i]^1]+=cc;        ans+=cc*v[p[i]];    }}   int main(){    n=sc(),a=sc(),b=sc(),f=sc(),fa=sc(),fb=sc();    S=2*n+1,T=S+1;    for(int i=1; i<=n; i++)    {        int x=sc();        insert(S,i,x,0);        insert(i+n,T,x,0);        insert(S,i+n,MX,f);        if(i+a+1<=n)insert(i,i+n+a+1,MX,fa);        if(i+b+1<=n)insert(i,i+n+b+1,MX,fb);        if(i+1<=n)insert(i,i+1,MX,0);    }    while(spfa())mcf();    cout << ans;}
1 0