洛谷P4014分配问题——网络流24题

题目:https://www.luogu.org/problemnew/show/P4014

最大/小费用最大流裸题。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
queue<int>q;
int const inf=1e9;
int n,t,head[205],ct=1,pre[205],mx,mn,incf[205],dis[205];
bool vis[205];
struct N{
    int hd,to,next,w,v;
    N(int h=0,int t=0,int n=0,int w=0,int v=0):hd(h),to(t),next(n),w(w),v(v) {}
}edge[15005],tmp[15005];
bool spfa()
{
    memset(dis,-2,sizeof dis);
    memset(incf,0x3f,sizeof incf);
    memset(vis,0,sizeof vis);
    memset(pre,0,sizeof pre);
    while(q.size())q.pop();
    dis[0]=0;vis[0]=1;q.push(0);
    while(q.size())
    {
        int x=q.front();q.pop();vis[x]=0;
        for(int i=head[x];i;i=edge[i].next)
        {
            int u=edge[i].to;
            if(dis[u]<dis[x]+edge[i].w&&edge[i].v)
            {
                dis[u]=dis[x]+edge[i].w;
                pre[u]=i;
                incf[u]=min(incf[x],edge[i].v);
                if(!vis[u])vis[u]=1,q.push(u);
            }
        }
    }
    return pre[t];
}
bool spfa2()
{
    memset(dis,0x3f,sizeof dis);
    memset(incf,0x3f,sizeof incf);
    memset(vis,0,sizeof vis);
    memset(pre,0,sizeof pre);
    while(q.size())q.pop();
    dis[0]=0;vis[0]=1;q.push(0);
    while(q.size())
    {
        int x=q.front();q.pop();vis[x]=0;
        for(int i=head[x];i;i=tmp[i].next)
        {
            int u=edge[i].to;
            if(dis[u]>dis[x]+tmp[i].w&&tmp[i].v)
            {
                dis[u]=dis[x]+tmp[i].w;
                pre[u]=i;
                incf[u]=min(incf[x],tmp[i].v);
                if(!vis[u])vis[u]=1,q.push(u);
            }
        }
    }
    return pre[t];
}
void mcf()
{
    memcpy(tmp,edge,sizeof edge);
    while(spfa())
    {
        mx+=incf[t]*dis[t];
        for(int i=pre[t];i;i=pre[edge[i].hd])
        {
            edge[i].v-=incf[t];
            edge[i^1].v+=incf[t];
        }
    }
    while(spfa2())
    {
        mn+=incf[t]*dis[t];
        for(int i=pre[t];i;i=pre[edge[i].hd])
        {
            tmp[i].v-=incf[t];
            tmp[i^1].v+=incf[t];
        }
    }
}
int main()
{
    scanf("%d",&n);
    t=2*n+2;
    for(int i=1;i<=n;i++)
    {
        edge[++ct]=(N){0,i,head[0],0,1};head[0]=ct;
        edge[++ct]=(N){i,0,head[i],0,0};head[i]=ct;
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            int x;
            scanf("%d",&x);
            edge[++ct]=(N){i,j+n,head[i],x,1};head[i]=ct;
            edge[++ct]=(N){j+n,i,head[j+n],-x,0};head[j+n]=ct;
        }
    for(int j=1;j<=n;j++)
    {
        edge[++ct]=(N){j+n,t,head[j+n],0,1};head[j+n]=ct;
        edge[++ct]=(N){t,j+n,head[t],0,0};head[t]=ct;
    }
    mcf();
    printf("%d\n%d",mn,mx);
    return 0;
}

 

posted @ 2018-04-10 18:37  Zinn  阅读(187)  评论(0编辑  收藏  举报