网络流24题 洛谷 4014 分配问题

Posted horsepower2001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络流24题 洛谷 4014 分配问题相关的知识,希望对你有一定的参考价值。

代码风格迥异 ……

技术分享图片
#include<bits/stdc++.h>

const int N=100+10,M=100000+10;

using namespace std;

queue<int> q;

int head[M],dis[M],flt[M],to[M],nxt[M],cn=1;
int c[N],pree[N],pred[N],a[N][N];
int maxcost,mincost,src,sink,tmp,n,x;
bool vis[N];

void create(int u,int v,int f,int d){
    cn++;
    to[cn]=v;
    nxt[cn]=head[u];
    dis[cn]=d;
    flt[cn]=f;
    head[u]=cn;
    cn++;
    to[cn]=u;
    nxt[cn]=head[v];
    dis[cn]=-d;
    flt[cn]=0;
    head[v]=cn;
}

bool spfamin(){
    while(!q.empty()) q.pop();
    memset(c,0x7f,sizeof(c));
    memset(vis,false,sizeof(vis));
    memset(pred,false,sizeof(pred));
    memset(pree,false,sizeof(pree));
    c[src]=0;
    vis[src]=true;
    q.push(src);
    while(!q.empty()){
        tmp=q.front();
        vis[tmp]=false;
        for(int i=head[tmp];i;i=nxt[i]){
            int v=to[i];
            if(flt[i]>0 && c[v]>c[tmp]+dis[i]){
                c[v]=c[tmp]+dis[i];
                pree[v]=i;
                pred[v]=tmp;
                if(!vis[v]){
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
        q.pop();
    }
    return c[sink]<0x7f;
}

bool spfamax(){
    while(!q.empty()) q.pop();
    for(int i=1;i<=2*n+2;i++)
        c[i]=-0x7f;
    memset(vis,false,sizeof(vis));
    memset(pred,false,sizeof(pred));
    memset(pree,false,sizeof(pree));
    c[src]=0;
    vis[src]=true;
    q.push(src);
    while(!q.empty()){
        tmp=q.front();
        vis[tmp]=false;
        for(int i=head[tmp];i;i=nxt[i]){
            int v=to[i];
            if(flt[i]>0 && c[v]<c[tmp]+dis[i]){
                c[v]=c[tmp]+dis[i];
                pree[v]=i;
                pred[v]=tmp;
                if(!vis[v]){
                    vis[v]=true;
                    q.push(v);
                }
            }
        }
        q.pop();
    }
    return c[sink]>0;
}

void augmentmin(){
    int delta=0x7f,u=sink;
    while(u!=src){
        if(flt[pree[u]]<delta)
            delta=flt[pree[u]];
        u=pred[u];
        
    }
    u=sink;
    while(u!=src){
        flt[pree[u]]-=delta;
        flt[pree[u]^1]+=delta;
        u=pred[u];
    }
    mincost+=delta*c[sink];
}

void augmentmax(){
    int delta=0x7f,u=sink;
    while(u!=src){
        if(flt[pree[u]]<delta)
            delta=flt[pree[u]];
        u=pred[u];
        
    }
    u=sink;
    while(u!=src){
        flt[pree[u]]-=delta;
        flt[pree[u]^1]+=delta;
        u=pred[u];
    }
    maxcost+=delta*c[sink];
}

int main(){
    
    ios::sync_with_stdio(false);
    
    cin>>n;
    
    
    src=0;sink=2*n+1;
    for(int i=1;i<=n;i++)
        create(src,i,1,0);
    for(int i=1;i<=n;i++)
        for(int j=1+n;j<=2*n;j++){
            cin>>a[i][j];
            create(i,j,1,a[i][j]);
        }
    for(int i=1+n;i<=2*n;i++)
        create(i,sink,1,0);
    while(spfamin())
        augmentmin();
    cout<<mincost<<endl;
    
    memset(head,0,sizeof(head));
    memset(nxt,0,sizeof(nxt));
    memset(to,0,sizeof(to));
    memset(dis,0,sizeof(dis));
    memset(head,0,sizeof(flt));
    cn=1;
    src=0;sink=2*n+1;
    for(int i=1;i<=n;i++)
        create(src,i,1,0);
    for(int i=1;i<=n;i++)
        for(int j=1+n;j<=2*n;j++){
            create(i,j,1,a[i][j]);
        }
    for(int i=1+n;i<=2*n;i++)
        create(i,sink,1,0);
    while(spfamax())
        augmentmax();
    cout<<maxcost;
    
    return 0;
}
Ans

以上是关于网络流24题 洛谷 4014 分配问题的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 P4014 分配问题 最小费用最大流+最大费用最大流

P4014 分配问题 网络流

费用流网络流24题P4014 分配问题.md

网络流24题 洛谷 2763 试题库问题

网络流24题 洛谷 2756 飞行员配对方案

网络流24题 洛谷 3254 圆桌问题