Test instructions
Give a matrix of each row and each column and, in the constraints given to some of the rows or points, seek a satisfying matrix.
Analysis:
to the upper and lower bounds of the network flow, note is equal to an upper and lower bounds, and then using the Dinic algorithm.
Code:
POJ 2396//sep9#include <iostream> #include <queue> #include <algorithm>using namespace Std;const int maxn=210;const int maxm=40;const int maxv=260;const int maxe=26000;struct edge{int u,v,f,nxt;} e[maxe*2+10];queue<int> que;int src,sink;int g[maxv+10];int nume;bool vis[maxv+10];int dist[maxV+10];int N,M, LOW[MAXN][MAXM],HIGH[MAXN][MAXM],IDS[MAXN][MAXM],R[MAXN],C[MAXM]; int ss,tt; void Addedge (int u,int v,int c) {e[nume].u=u,e[nume].v=v;e[nume].f=c;e[nume].nxt=g[u];g[u]=nume++;e[nume].u=v;e[ nume].v=u;e[nume].f=0;e[nume].nxt=g[v];g[v]=nume++;} void update (int x1,int x2,int y1,int Y2,char op,int z) {for (Int. i=x1;i<=x2;++i) for (int j=y1;j<=y2;++j) {if (op== ' = ') Low[i][j]=max (Low[i][j],z), High[i][j]=min (high[i][j],z), else if (op== ' < ') high[i][j]=min (high[i][j],z-1); Elselow[i][j]=max (low[i][j],z+1);}} int check () {for (Int. i=1;i<=n;++i) for (int j=1;j<=m;++j) if (Low[i][j]>high[i][j]) return 0;return 1;} void Init () {memset (g,0,sizeof (g)); Nume=2;int I,j,k,x,y,z,c;char op[16];scanf ("%d%d", &n,&m); memset (low,0,sizeof (Low)), memset (high,0x7f,sizeof), for (I=1;i<=n;++i) scanf ("%d", &r[i]); for (i=1;i <=m;++i) scanf ("%d", &c[i]), scanf ("%d", &c), while (c--) {scanf ("%d%d%s%d", &x,&y,op,&z); if (x= =0&&y==0) Update (1,N,1,M,OP[0],Z), else if (x==0) update (1,N,Y,Y,OP[0],Z), else if (y==0) update (x,x,1,m,op[0], z); else update (X,X,Y,Y,OP[0],Z);}} int BFs () {while (!que.empty ()) Que.pop (); memset (dist,0,sizeof (Dist)); memset (vis,0,sizeof (Vis)); vis[src]=true; Que.push (SRC), while (!que.empty ()) {int U=que.front (), Que.pop (), for (int i=g[u];i;i=e[i].nxt) if (e[i].f&&! VIS[E[I].V]) {Que.push (E[I].V);d ist[e[i].v]=dist[u]+1;vis[e[i].v]=true; if (e[i].v==sink) return 1;}} return 0;} int dfs (int u,int delta) {if (U==sink) return delta;int ret=0;for (int i=g[u];ret<delta&&i;i=e[i].nxt) if (E[i] . f&&dist[e[i].v]==dist[u]+1) {int Dd=dfs (e[i].v,min (E[i].f,delta-ret)), if (dd>0) {e[i].f-=dd;e[i^1].f+= DD;RET+=DD;} Elsedist[e[i].v]=-1;} return ret;} INT Dinic () {int ret=0;while (BFS () ==1) Ret+=dfs (Src,int_max); return ret;} int build () {int I,j,sum=0;src=0,sink=n+m+1,ss=sink+1;tt=sink+2;addedge (SINK,SRC,INT_MAX); for (I=1;i<=n;++i) { Addedge (Ss,i,r[i]); Addedge (Src,tt,r[i]); sum+=r[i];} for (i=1;i<=m;++i) {Addedge (ss,sink,c[i]); Addedge (N+i,tt,c[i]); sum+=c[i];} for (I=1;i<=n;++i) for (j=1;j<=m;++j) {Ids[i][j]=nume+1;addedge (i,n+j,high[i][j]-low[i][j]); Addedge (SS,N+j, LOW[I][J]); Addedge (I,tt,low[i][j]); sum+=low[i][j];} return sum;} void Solve () {if (!check ()) {puts ("impossible"); return;} int Sum=build (); Src=ss,sink=tt;if (Sum!=dinic ()) puts ("impossible"); else{for (int i=1;i<=n;++i) {for (int j=1;j< =M;++J) printf ("%d", E[ids[i][j]].f+low[i][j]);p rintf ("\ n");}} int main () {int cases;scanf ("%d", &cases), while (cases--) {init (); solve ();p rintf ("\ n");} return 0;}
POJ 2396 Budget edge capacity with upper and lower bounds of maximum flow