网络流-最大流&最小费用最大流

来源:互联网 发布:移动硬盘mac无法拷贝 编辑:程序博客网 时间:2024/04/28 21:04

isap递归版
最大流

#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>using namespace std;const int maxn=1010;int p[maxn][maxn],d[maxn],gap[maxn];int isap(int x,int flow){    if(x==t) return flow;    int res=flow;    for(int i=1;i<=n;i++)if(p[x][i] && d[x]==d[i]+1){        int Min=isap(i,min(res,p[x][i]));//        p[x][i]-=Min;p[i][x]+=Min;        res-=Min;        if(!res) return flow;    }    if(!(--gap[d[x]])) d[s]=t;    ++gap[++d[x]];    return flow-res;}int main(){    for(gap[0]=t;d[s]<t;){        maflow+=isap(s,INF);    }    return 0;}

最小费用最大流(SPFA)

#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<queue>using namespace std;const int maxn=2500;const int INF=1e9;int to[maxn*10],Begin[maxn],Next[maxn*10],flow[maxn*10],e,cost[maxn*10];int s,t;int pre[maxn],dis[maxn];int vis[maxn];void add(int x,int y,int w,int c){    to[++e]=y;    Next[e]=Begin[x];    Begin[x]=e;    flow[e]=w;    cost[e]=c;}void addedge(int x,int y,int w,int c){    add(x,y,w,c);    add(y,x,0,-c);}bool spfa(){    memset(pre,0,sizeof(pre));    for(int i=1;i<=t;i++) dis[i]=INF;    queue<int>q;    q.push(s);    dis[s]=0;    while(!q.empty()){        int u=q.front();q.pop();        vis[u]=0;        for(int i=Begin[u];i;i=Next[i]){            int v=to[i];            if(flow[i] && dis[v]>dis[u]+cost[i]){                dis[v]=dis[u]+cost[i];                pre[v]=i^1;                if(vis[v]) continue;                vis[v]=1;                q.push(v);            }        }    }    return pre[t];}int maxflow(){    int ans=0;    while(spfa()){        int _min=INF;        for(int i=pre[t];i;i=pre[to[i]]) if(flow[i^1]<_min) _min=flow[i^1];        for(int i=pre[t];i;i=pre[to[i]]){            flow[i]+=_min;            flow[i^1]-=_min;        }        ans+=_min*dis[t];    }    return ans;}int num[maxn];int main(){    int n,a,b,f,fa,fb;    e=1;    scanf("%d%d%d%d%d%d",&n,&a,&b,&f,&fa,&fb);    for(int i=1;i<=n;i++)scanf("%d",&num[i]);    s=2*n+1;    t=s+1;    for(int i=1;i<=n;i++){        addedge(s,i,num[i],0);        addedge(i+n,t,num[i],0);        addedge(s,i+n,INF,f);        if(i+1<=n)addedge(i,i+1,INF,0);        if(i+1+a<=n)addedge(i,i+n+a+1,INF,fa);        if(i+1+b<=n)addedge(i,i+n+b+1,INF,fb);    }    printf("%d",maxflow());    return 0;}

^_^

1 0
原创粉丝点击