Topic Links:
zoj1994
Title Description:
A budget is now set for a multi-zone contest, which is a matrix that represents the different kinds of expenses and represents the expenses of different divisions. The organizing committee has held a meeting to discuss the sum of all kinds of expenses, as well as the total cost of each division. In addition, the organizing Committee discussed a number of special constraints: for example, it was suggested that the computer centre needed at least 1000K (Iranian currency) for food purchases, and that the cost of Sharif Division for the purchase of T-shirts could not exceed 30000K. The task of the organizing Committee is to develop a budget that meets all constraints and requirements.
Problem Solving Report:
The key is to build the diagram, put the row on the left, the column to the right, and then connect all the rows and columns, each side represents the price budget for items in column x row y.
The upper and lower bounds of these edges are qualified according to the constraint conditions, and the problem is transformed into a feasible flow solution with upper-down bounds:
The right to an existing edge is c[i][j]-b[i][j]
Also constructs source and sink points to connect all rows and all columns, respectively.
Benquan for Sum[x]-sum (B[x][i]) sum[y]-sum (B[i][y])
If the source and catchment are equal, there is a feasible solution
Code:
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include < queue>const int MAXN =505;const int maxm=440020;const int Inf=0x3f3f3f;const int maxx=0x3f3f3f3f;using namespace Std;s truct Edge {int to,cap,flow,next;} edge[maxm];int head[maxn],tot,gap[maxn],d[maxn],cur[maxn],que[maxn],p[maxn];void Init () {tot=0; memset (head,-1,sizeof (Head));} int isap (int source,int sink,int N) {memset (gap,0,sizeof (GAP)); Memset (d,0,sizeof (d)); memcpy (cur,head,sizeof (head)); int top = 0,x = Source,flow = 0; while (D[source] < N) {if (x = = sink) {int Min = maxx,inser=0; for (int i = 0; i < top; ++i) {if (min > Edge[p[i]].cap-edge[p[i]].flow) {min = Edge[p[i]].cap-edge[p[i]].flow; Inser = i; }} for (int i = 0; i < top; ++i) {edge[p[i]].flow + = Min; Edge[p[i]^1].flow-=Min; } if (min!=inf) flow + = Min; top = Inser; x = edge[p[top]^1].to; Continue } int ok = 0; for (int i = cur[x]; i =-1; i = edge[i].next) {int v = edge[i].to; if (Edge[i].cap > edge[i].flow && d[v]+1 = = D[x]) {OK = 1; CUR[X] = i; p[top++] = i; x = edge[i].to; Break }} if (!ok) {int Min = N; for (int i = head[x]; i =-1; i = edge[i].next) {if (Edge[i].cap > Edge[i].flow && d[edge[i].to] < min) {min = d[edge[i].to]; CUR[X] = i; }} if (--gap[d[x] = = 0) break; GAP[D[X] = min+1]++; if (x! = source) x = edge[p[--top]^1].to; }} return flow;} int b[205][25],h[205][25];int Sumr[205],sumc[205];int id[205][25]; Used to save [i][j] The number of sides of the adjacency table int s,t;int n,m;int sum;int flag;void addedge (int u,int v,int c,int x,int y) {edge[tot]= (edge) {V,c,0,head[u]} ; id[x][y]= Head[u] = tot++; Edge[tot]= (Edge) {u,c,c,head[v]}; HEAD[V] = tot++;} void set_ (int x,int Y,char Ch,int v) {if (ch== ' = ') {if (b[x][y]>v) flag=1; if (h[x][y]<v) flag=1; B[x][y]=h[x][y]=v; } else if (ch== ' > ') {if (h[x][y]<=v) flag=1; B[x][y]=max (b[x][y],v+1); } else {if (b[x][y]>=v) flag=1; H[x][y]=min (H[x][y],v-1); }}void build () {for (Int. i=1;i<=n;i++) for (int j=1;j<=m;j++) Addedge (I,N+J,H[I][J]-B[I][J],I,J); for (int i=1;i<=n+m;i++) {int f=i<=n?sumr[i]:-sumc[i-n]; if (i<=n) for (int j=1;j<=m;j++) F-=B[I][J]; else for (int j=1;j<=n;j++) f+=b[j][i-n]; if (f>0) {Addedge (s,i,f,0,0); Sum+=f; } else Addedge (i,t,-f,0,0); }}int Main () {//Freopen ("In.txt", "R", stdin); int T; int nn,a,bb,c; Char ch; scanf ("%d", &t); for (int case=1; case<=t; case++) {if (case!=1) printf ("\ n"); scanf ("%d%d", &n,&m); Init (); s=0,t=n+m+1; sum=0; flag=0; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++)//initial upper and lower bounds {b[i][j]=0; H[i][j]=inf; } for (int i=1;i<=n;i++) scanf ("%d", &sumr[i]); for (int j=1;j<=m;j++) scanf ("%d", &sumc[j]); scanf ("%d", &nn); while (nn--)//qualifying upper and lower bounds {cin>>a>>bb>>ch>>c; if (!A&&!BB) {for (Int. i=1;i<=n;i++) for (int j=1;j<=m;j++) set_ (I,J,CH,C); } else if (!A&&BB) {for (int i=1;i<=n;i++) set_ (I,BB,CH,C); } else if (A&&!BB) {for (int i=1;i<=m;i++) set_ (a,i,ch,c ); } else set_ (A,BB,CH,C); } if (flag==1) {//constraint conditions are contradictory to printf ("impossible\n"); Continue } build (); int Ans=isap (s,t,t+1); if (Sum!=ans)//Source = = Confluence printf ("impossible\n"); else {for (Int. i=1;i<=n;i++) for (int j=1;j<=m;j++) if (j==m) printf ("%d\n", B[i][j]+edge[id[i][j]].flow); else printf ("%d", b[i][j]+edge[id[i][j]].flow); }} return 0;}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Solution of feasible flow in upper and lower bounds of zoj1994/poj2396 Budget