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

Posted ws_yzy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 1221: [HNOI2001] 软件开发|费用流相关的知识,希望对你有一定的参考价值。

把每天分为二分图两个集合中的顶点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 200000000
using 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;

以上是关于BZOJ 1221: [HNOI2001] 软件开发|费用流的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1221 [HNOI2001] 软件开发

bzoj 1221: [HNOI2001] 软件开发

BZOJ1221HNOI2001软件开发 [费用流]

费用流BZOJ1221-[HNOI2001] 软件开发

BZOJ1221: [HNOI2001] 软件开发

bzoj1221[HNOI2001] 软件开发 费用流