最大流 二分图模型
X 集合为行, Y集合为列, 对每个数来说,bom[i][j]表示最小的,upp表示最大的。
之后连S到X,Y到T, 求从S到Y的可行流
求可行流时。。 添加附加源点ss,tt...
之后建图方式与 http://blog.csdn.net/hlyfalsy/article/details/38555467 SGU 176 类似。。
//tpl //ipqhjjybj_tpl.h //header.h #include #include #include #include #include #include #include #include #include #include #include #include #define mp(x,y) make_pair(x,y) #define pii pair #define pLL pair #define pb(x) push_back(x) #define rep(i,j,k) for(int i = j; i < k;i++) #define MAX(x,a) x=((x)<(a))?(a):(x) #define MIN(x,a) x=((x)>(a))?(a):(x) using namespace std; const int N = 305; int n,m,tot; int s,t; int sum; struct node{ int u,v,w,next; node(){} node(int _u,int _v,int _w,int _next){ u=_u,v=_v,w=_w,next=_next; } }edge[N*N]; int head[N],cur[N],dis[N]; int pre[N],gap[N],aug[N]; const int oo=0x3f3f3f3f; void addEdge(int u,int v,int w){ edge[tot]=node(u,v,w,head[u]); head[u]=tot++; edge[tot]=node(v,u,0,head[v]); head[v]=tot++; } int SAP(int s,int e,int n){ int max_flow=0,v,u=s; int id,mindis; aug[s]=oo; pre[s]=-1; memset(dis,0,sizeof(dis)); memset(gap,0,sizeof(gap)); gap[0]=n; for(int i=0;i <= n;i++) cur[i]=head[i]; while(dis[s] 0 && dis[u]==dis[v]+1){ flag=true; pre[v]=u; cur[u]=id; aug[v]=min(aug[u],edge[id].w); u=v; break; } } if(flag==false){ if(--gap[dis[u]] == 0) break; int mindis=n; for(id=head[u]; id!=-1; id=edge[id].next){ v=edge[id].v; if(edge[id].w>0 && dis[v] < mindis){ mindis = dis[v]; cur[u]=id; } } dis[u] = mindis + 1; gap[dis[u]]++; if(u!=s)u=pre[u]; } } return max_flow; } int r[N],c[N]; int bom[N][N],upp[N][N]; int in[N]; int fs; void print(){ int row = 1; int col = 1; for(int i = 1;i < fs;i+=2){ printf("%d",edge[i].w+bom[row][col]); if(col == m){ row++; col = 1; printf("\n"); }else { col++; printf(" "); } } } int solve(){ int src = s , des = t; s = des+1, t = s+1; int max_flow = 0; rep(i,0,des+1) if(in[i] > 0)addEdge(s,i,in[i]),max_flow+=in[i]; else if(in[i] < 0) addEdge(i,t,-in[i]); // printf("max_flow = %d\n",max_flow); // printf("s=%d t=%d src=%d des=%d \n",s,t,src,des); int s1 = SAP(s,t,t+1); addEdge(des,src,oo); int s2 = SAP(s,t,t+1); // printf("s1=%d s2=%d\n",s1,s2); if(s1 + s2 == max_flow) return 1; else return -1; } int main(){ int cas; int hang_flag = true; scanf("%d",&cas); while(cas--){ if(hang_flag)hang_flag = false; else printf("\n"); scanf("%d %d",&n,&m); memset(head,-1,sizeof(head)); memset(in,0,sizeof(in)); tot = s = sum =0; rep(i,1,n+1) scanf("%d",r+i); rep(i,1,m+1) scanf("%d",c+i); memset(bom,0,sizeof(bom)); rep(i,1,n+1) rep(j,1,m+1) upp[i][j] = oo; int q; scanf("%d",&q); char op[10]; bool flag = true; while(q--){ int u,v,w; scanf("%d %d %s %d",&u,&v,op,&w); int tu1 = u ,tu2 = u , tv1 = v,tv2 = v; if(u == 0) tu1 = 1,tu2 = n; if(v == 0) tv1 = 1,tv2 = m; rep(i,tu1,tu2+1) rep(j,tv1,tv2+1){ if(op[0] == '<') if(bom[i][j]>=w)flag=false; else MIN(upp[i][j],w-1); else if(op[0] == '>') if(upp[i][j]<=w)flag=false; else MAX(bom[i][j],w+1); else if(bom[i][j]>w||upp[i][j]= 0){ print(); }else{ puts("IMPOSSIBLE"); } } return 0; }