739. [Network Flow 24 questions] transport issues
★ ☆ Input File: tran.in output file: Tran.out Simple contrast
time limit: 1 s memory limit: MB
«Problem Description:
«Programming tasks:
For the cost of transporting goods between a given m warehouse and N retail stores, calculate the optimal transport plan and the worst transport plan.
«Data Entry:
«result output:
At the end of the program run, the calculated minimum shipping cost and the maximum shipping cost are output to the file tran.out.
Example output file for input file sample
Tran.in
2 3
280 (
150 186 122)
Tran.out
48500
69140
For all data: 1<=n,m<=100
The following:
It's easier to think about the cost stream.
Build diagram:
1> set up virtual sources s and sinks T.
2> from S to M warehouses with a flow rate of a[i], with a cost of 0 sides.
3> from n stores to T for B[i], with a cost of 0 sides.
4> from M warehouses to n stores, with an infinity, cost of c[i][j] edge.
Then run for the minimum cost, and then run one side of the maximum cost is good.
Code:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath
> #include <algorithm> #define N 310 #define M 30010 #define INF 0x7ffffff using namespace std; struct edge{int v,next,cap,cost;}
EDGE[M];
int n,m,num,ans,s,t,a[n],b[n],c[n][n];
int head[n],flow[n],prep[n],prev[n],dis[n],q[m];
BOOL Vis[n];
int in () {int x=0; char Ch=getchar ();
while (ch< ' 0 ' | | ch> ' 9 ') Ch=getchar ();
while (ch>= ' 0 ' && ch<= ' 9 ') x=x*10+ch-' 0 ', Ch=getchar ();
return x;
} void Add (int u,int v,int cap,int cost) {edge[++num].v=v; edge[num].next=head[u]; head[u]=num; Edge[num].cap=cap;
Edge[num].cost=cost;
} void Build () {s=0,t=m+n+1;
for (int i=1; i<=m; i++) Add (s,i,a[i],0), add (i,s,0,0);
for (int i=1; i<=n; i++) Add (i+m,t,b[i],0), add (t,i+m,0,0);
for (int. I=1; i<=m; i++) for (int j=1; j<=n; j + +) Add (I,j+m,inf,c[i][j]), add (J+m,i,0,-c[i][j]); } bool SPFA (int k) {int h=0,t=1;
if (k>0) memset (dis,0x3f,sizeof (dis));
Else memset (dis,128,sizeof (dis));
memset (vis,0,sizeof (VIS)); dis[s]=0; Q[h]=s;
Vis[s]=1; Flow[s]=inf;
Prep[s]=-1;
while (h<t) {int u=q[h++]; vis[u]=0;
for (int i=head[u]; i; i=edge[i].next) {int v=edge[i].v; if (edge[i].cap>0 && (k>0 && dis[v]>dis[u]+edge[i].cost) | | (k<0 && dis[v]<dis[u]+edge[i].cost)))
{dis[v]=dis[u]+edge[i].cost; Prep[v]=u;
Prev[v]=i;
Flow[v]=min (FLOW[U],EDGE[I].CAP);
if (!vis[v]) vis[v]=1,q[t++]=v;
}}} if (k>0) {if (Dis[t]>inf) return 0;
else return 1;
} else {if (dis[t]<0) return 0;
else return 1;
}} void Work () {for (int i=t; i!=s; I=prep[i]) {edge[prev[i]].cap-=flow[t];
EDGE[PREV[I]^1].CAP+=FLOW[T]; } ans+=flow[t]*DIS[T];
} int main () {m=in (), N=in ();
for (int i=1; i<=m; i++) a[i]=in ();
for (int i=1; i<=n; i++) b[i]=in ();
for (int i=1, i<=m; i++) for (int j=1; j<=n; j + +) C[i][j]=in (); Num=1; Build ();
ans=0;
while (SPFA (1)) work ();
printf ("%d\n", ans);
memset (head,0,sizeof (head));
memset (prep,0,sizeof (Prep));
memset (prev,0,sizeof (prev));
memset (flow,0,sizeof (flow)); Num=1; Build ();
ans=0;
while (SPFA ( -1)) work ();
printf ("%d\n", ans);
return 0; }