住民は基本的に交通問題を改善されて

6011「ネットワークフロー24個の質問」交通問題

フェイス質問

この質問は非常に巨大な水のああです。

人類の未来は、この質問の飲料水の供給に依存しています。

最初に問題の意味を理解します。

そこ\(m個\)倉庫、\(私は\)倉庫番目の\は(a_iを\)商品がき番目の\(\ N-)店、\は(私が\)保存が必要です\(B_i \)目を最初から商品\(iは\)最初に出荷倉庫\(Jの\)コストストアである\(C_ {IJ} \)

だから、ネットワークフローモデルであっても、ウェアハウス・ソース、流れに、出てきた\(a_iを\) コスト(\ 0 \) 倉庫や店舗、フローの間に接続されている\(INF \)の費用\ (C_ {のIJ} \) シンク・ストアに接続され、フロー\(B_i \)コスト(\ 0 \)

もう一度実行してください(MCMF \)\最小コストを得ること。

そして、否定コストを与え、再びピットイン(MCMF \)\最大の手数料を見つけます。

コード:


#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;
}

おすすめ

転載: www.cnblogs.com/Lemir3/p/11161587.html