Residents been fundamentally improved transportation problem

6011. "network flow 24 questions" transportation problem

Face questions

This question is extremely huge water ah.

The future of mankind rely on drinking water supply of this question.

At first understand the meaning of problems.

There \ (m \) warehouse, the \ (I \) th warehouse \ (a_i \) th goods have \ (n-\) stores, the \ (I \) stores requires \ (B_i \) th goods from the first \ (i \) warehouse shipped to the first \ (j \) a cost store is \ (c_ {ij} \) .

So network flow model came out, even to the warehouse source, flow \ (a_i \) , cost \ (0 \) . Is connected between the warehouse and the store, flow \ (INF \) , cost of \ (C_ {ij of} \) , connected to the sink store, flow \ (B_i \) , cost \ (0 \) .

Run again \ (MCMF \) to obtain the minimum cost.

Then give the cost negated, pitted again \ (MCMF \) find the maximum fee.

Code:


#include "cstdio"
#include "cstring"
#include "algorithm"
#include "iostream"
#include "cmath"
#include "queue"

#define debug(x) printf("debug:%lld\n",x)
#define ll long long
#define INF 2147483647

using namespace std;

struct edge
{
    ll to,next,flow,cost;
}e1[500010],e2[500010];

queue<ll>q1,q2;

ll m,n,start,end,size1,size2,mincost,maxcost;//m个仓库,n个商店.
ll head1[10010],dis1[10010],flow1[10010],last1[10010],pre1[10010];
ll head2[10010],dis2[10010],flow2[10010],last2[10010],pre2[10010];
bool flag1[10010];
bool flag2[10010];

inline void EdgeAdd1(ll,ll,ll,ll);
inline void EdgeAdd2(ll,ll,ll,ll);
inline void MCMF1();
inline void MCMF2();
inline bool SPFA1();
inline bool SPFA2();

signed main(void)
{
    memset(head1,-1,sizeof(head1));
    memset(head2,-1,sizeof(head2));
    scanf("%lld%lld",&m,&n);
    start=0;
    end=m+n+1;
    for(ll _=1;_<=m;_++)
    {
        ll val;
        scanf("%lld",&val);
        EdgeAdd1(start,_,val,0);
        EdgeAdd1(_,start,0,0);
        EdgeAdd2(start,_,val,0);
        EdgeAdd2(_,start,0,0);
    }
    for(ll _=1;_<=n;_++)
    {
        ll val;
        scanf("%lld",&val);
        EdgeAdd1(_+m,end,val,0);
        EdgeAdd1(end,_+m,0,0);
        EdgeAdd2(_+m,end,val,0);
        EdgeAdd2(end,_+m,0,0);
    }
    for(ll _=1;_<=m;_++)
    {
        for(ll __=1;__<=n;__++)
        {
            ll cost;
            scanf("%lld",&cost);
            EdgeAdd1(_,__+m,INF,cost);
            EdgeAdd1(__+m,_,0,-cost);
            EdgeAdd2(_,__+m,INF,-cost);
            EdgeAdd2(__+m,_,0,cost);
        }
    }
    MCMF1();
    MCMF2();
    printf("%lld\n%lld\n",mincost,-maxcost);
return 0;
}

inline void EdgeAdd1(ll from,ll to,ll flow,ll cost)
{
    e1[size1].to=to;
    e1[size1].flow=flow;
    e1[size1].cost=cost;
    e1[size1].next=head1[from];
    head1[from]=size1++;
}

inline void EdgeAdd2(ll from,ll to,ll flow,ll cost)
{
    e2[size2].to=to;
    e2[size2].flow=flow;
    e2[size2].cost=cost;
    e2[size2].next=head2[from];
    head2[from]=size2++;
}

inline void MCMF1()
{
    while(SPFA1())
    {
        ll now=end;
        mincost+=flow1[end]*dis1[end];
        while(now!=start)
        {
            e1[last1[now]].flow-=flow1[end];
            e1[last1[now]^1].flow+=flow1[end];
            now=pre1[now];
        }
    }
}

inline void MCMF2()
{
    while(SPFA2())
    {
        ll now=end;
        maxcost+=flow2[end]*dis2[end];
        while(now!=start)
        {
            e2[last2[now]].flow-=flow2[end];
            e2[last2[now]^1].flow+=flow2[end];
            now=pre2[now];
        }
    }
}

inline bool SPFA1()
{
    memset(dis1,0x3f,sizeof(dis1));
    memset(flag1,false,sizeof(flag1));
    memset(flow1,0x3f,sizeof(flow1));
    q1.push(start);
    pre1[end]=-1;
    dis1[start]=0;
    flag1[start]=true;
    while(q1.empty()==false)
    {
        ll from=q1.front();
        q1.pop();
        flag1[from]=false;
        for(ll _=head1[from];_!=-1;_=e1[_].next)
        {
            ll to=e1[_].to;
            ll cost=e1[_].cost;
            ll flow_=e1[_].flow;
            if(flow_>0&&dis1[to]>dis1[from]+cost)
            {
                dis1[to]=dis1[from]+cost;
                pre1[to]=from;
                last1[to]=_;
                flow1[to]=min(flow1[from],flow_);
                if(flag1[to]==false)
                {
                    q1.push(to);
                    flag1[to]=true;
                }
            }
        }
    }
return pre1[end]==-1?false:true;
}

inline bool SPFA2()
{
    memset(flag2,false,sizeof(flag2));
    memset(dis2,0x3f,sizeof(dis2));
    memset(flow2,0x3f,sizeof(flow2));
    q2.push(start);
    flag2[start]=true;
    dis2[start]=0;
    pre2[end]=-1;
    while(!q2.empty())
    {
        ll from=q2.front();
        q2.pop();
        flag2[from]=false;
        for(ll _=head2[from];_!=-1;_=e2[_].next)
        {
            ll to=e2[_].to;
            ll cost=e2[_].cost;
            ll flow_=e2[_].flow;
            if(flow_>0&&dis2[to]>dis2[from]+cost)
            {
                dis2[to]=dis2[from]+cost;
                pre2[to]=from;
                last2[to]=_;
                flow2[to]=min(flow2[from],flow_);
                if(flag2[to]==false)
                {
                    q2.push(to);
                    flag2[to]=true;
                }
            }
        }
    }
return pre2[end]==-1?false:true;
}

Guess you like

Origin www.cnblogs.com/Lemir3/p/11161587.html