6011. "network flow 24 questions" transportation problem
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;
}