Test instructions: Given a n*m lattice, each lattice can fill 0-k integers. Then give the sum of each column and the sum of each line, ask whether there is a solution, some words is not the only solution, is the only solution output.
Idea: Network flow, a total of n+m+2 point source points to the line of traffic to the current line of the sum. Each row is connected to each column with a flow of k, each column to a sink point and a column. If the traffic equals the sum there is a solution, whereas the inverse is no solution (if the sum of the columns is not equal to the sum of rows). Determine whether the scheme is the only one to find the residual network is more than 2 length of the ring can be, the ring description is not unique.
#include <cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<iostream>#include<climits>using namespacestd;Const intN = +;Const intM =1000000;intN;intecnt, Head[n], nx[m], to[m], va[m], cur_edge[n];intsource, target, Flow, pre[n], lev[n], qu[n], sign;voidAddedge (intUintVintW) {to[ecnt]=v; NX[ECNT]=Head[u]; VA[ECNT]=W; Head[u]= ecnt++;}BOOLBFsintSintt) {Std::fill (Lev, Lev+ N,-1); Sign=T; Lev[t]=0; intSt =0, ed =0; Qu[ed++] =T; while(St! = ed && Lev[s] = =-1) { intU = qu[st++]; for(inti = Head[u]; I! =-1; i =Nx[i]) { if(va[i ^1] >0&& Lev[to[i]] = =-1) {Lev[to[i]]= Lev[u] +1; Qu[ed++] =To[i]; } } } returnLev[s]! =-1;}voidpush () {intDelta =int_max, u, p; for(U = target; u! = source; u = to[p ^1]) {p=Pre[u]; Delta=std::min (Delta, va[p]); } for(U = target; u! = source; u = to[p ^1]) {p=Pre[u]; VA[P]-=Delta; if(!va[p]) {//Note Double when you want to changeSign = to[p ^1]; } va[p^1] +=Delta; } Flow+=Delta;}voidDfsintu) {if(U = =target) push (); Else { for(inti = Cur_edge[u]; I! =-1; i =Nx[i]) { if(Va[i] >0&& Lev[u] = = Lev[to[i]] +1) {Pre[to[i]]=i; DFS (To[i]); if(Lev[sign] >Lev[u]) { return; } Sign=Target; }} Lev[u]= -1; }}voidDinic (intSintTintnode_cnt) {Source=s; Target=T; N=node_cnt; //Construct GraphFlow=0; while(BFS (source, target)) { for(inti =0; I < n; ++i) {Cur_edge[i]=Head[i]; } dfs (source); }}intNC, KC, MC, Sum1, sum2;intr[410], c[410];voidinit () {sum1= Sum2 =0; for(inti =0; I < NC; ++i) {scanf ("%d", &R[i]); Sum1+=R[i]; } for(inti =0; I < MC; ++i) {scanf ("%d", &C[i]); Sum2+=C[i]; }}intFlag =0;BOOLbo[ +];BOOLbb[ +];intcas[350000];intRI =0;voidGaointNowintFA) {//Find ringif(flag)return; //printf ("->%d", now);Bo[now] =true; for(inti = Head[now]; I! =-1; i =Nx[i]) { intU =To[i]; if(U = =FA)Continue; if(Va[i] = =0) Continue; //printf ("{%d%d}\n", now,u); if(Bb[u]) {//puts ("fuck");Flag =1; return; } if(Cas[i] = =RI)Continue; Cas[i]=RI; //if (Bo[u]) continue;Bb[u] =true; Gao (U, now); Bb[u]=false; }}voidsolve () {if(Sum1! =sum2) {Puts ("Impossible"); return; } Std::fill (head, head+ MC + NC +5, -1); ECNT=0; ints, t; S= NC +MC; T= S +1; //printf ("st:%d%d\n", s,t); for(inti =0; I < NC; ++i) { for(intj =0; J < MC; ++j) {//printf ("[%d%d]\n", I,J+NC);Addedge (i, J +NC, KC); Addedge (J+ NC, I,0); } } for(inti =0; I < NC; ++i) {//printf ("[%d%d]\n", s,i);Addedge (S, I, r[i]); Addedge (i, S,0); } for(inti =0; I < MC; ++i) {//printf ("[%d%d]\n", i+nc,t);Addedge (i +NC, T, C[i]); Addedge (t, I+ NC,0); } dinic (S, T, T+2); //printf ("flow:%d\n", flow); if(Flow = =sum1) {memset (bo,0,sizeof(bo)); memset (BB,0,sizeof(BB)); Flag=0; for(inti =0; I <= t; ++i) {if(flag) Break; Bb[i]=true; Gao (i,-1); Bb[i]=false; } if(flag) puts ("Not Unique"); Else{puts ("Unique"); for(inti =0; I < NC; ++i) { for(intj =0; J < MC; ++j) {intnow = i * MC +J; printf ("%d", Va[now <<1|1]); if(j = = MC-1) puts (""); Elseprintf (" "); } } } } Elseputs ("Impossible");}intMain () {memset (CAS,0,sizeof(CAS)); while(SCANF ("%d%d%d", &NC, &MC, &KC)! =EOF) { ++RI; Init (); Solve (); } return 0;}