POJ 2396 Budget 有上下界的可行网络流

来源:互联网 发布:网络电爱录音沈婷 编辑:程序博客网 时间:2024/05/18 01:00

Budget
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 8063 Accepted: 3029 Special Judge

Description

We are supposed to make a budget proposal for this multi-site competition. The budget proposal is a matrix where the rows represent different kinds of expenses and the columns represent different sites. We had a meeting about this, some time ago where we discussed the sums over different kinds of expenses and sums over different sites. There was also some talk about special constraints: someone mentioned that Computer Center would need at least 2000K Rials for food and someone from Sharif Authorities argued they wouldn't use more than 30000K Rials for T-shirts. Anyway, we are sure there was more; we will go and try to find some notes from that meeting. 

And, by the way, no one really reads budget proposals anyway, so we'll just have to make sure that it sums up properly and meets all constraints.

Input

The first line of the input contains an integer N, giving the number of test cases. The next line is empty, then, test cases follow: The first line of each test case contains two integers, m and n, giving the number of rows and columns (m <= 200, n <= 20). The second line contains m integers, giving the row sums of the matrix. The third line contains n integers, giving the column sums of the matrix. The fourth line contains an integer c (c < 1000) giving the number of constraints. The next c lines contain the constraints. There is an empty line after each test case. 

Each constraint consists of two integers r and q, specifying some entry (or entries) in the matrix (the upper left corner is 1 1 and 0 is interpreted as "ALL", i.e. 4 0 means all entries on the fourth row and 0 0 means the entire matrix), one element from the set {<, =, >} and one integer v, with the obvious interpretation. For instance, the constraint 1 2 > 5 means that the cell in the 1st row and 2nd column must have an entry strictly greater than 5, and the constraint 4 0 = 3 means that all elements in the fourth row should be equal to 3.

Output

For each case output a matrix of non-negative integers meeting the above constraints or the string "IMPOSSIBLE" if no legal solution exists. Put one empty line between matrices.

Sample Input

22 3 8 10 5 6 7 4 0 2 > 2 2 1 = 3 2 3 > 2 2 3 < 5 2 2 4 5 6 7 1 1 1 > 10

Sample Output

2 3 3 3 3 4 IMPOSSIBLE 

Source

Tehran 2003 Preliminary


一个矩阵,给出每行和每列的和,再给出某行、某列、某元素的大小限制,求出这样一个矩阵,或者输出Impossible.


把每行、每列看做一个点。源点连接每行,汇点连接每列,流量为行和或者列和;每对行列之间连边,表示这一行列交叉的位置的元素,流量的上下界就为这一个元素的上下界。

之后求有源点汇点的有上下界的可行流。


求有上下界、有源汇的可行流的方法:新添加新的源点和汇点,统计每个点流入和流出的量,流入多则连源点,流出多则连汇点,流量为多出的流。原图当中的边,每条边的流量变为流量上界减去下界。对于原来的源点汇点,添加边(t,s,inf),以平衡流量。

最后跑最大流,如果新源点出发的所有边都满流,则存在可行流。


#include <cstdio>#include <iostream>#include <string.h>#include <string> #include <map>#include <queue>#include <vector>#include <set>#include <algorithm>#include <math.h>#include <cmath>#include <stack>#define mem0(a) memset(a,0,sizeof(a))#define meminf(a) memset(a,0x3f,sizeof(a))using namespace std;typedef long long ll;typedef long double ld;typedef double db;const int maxn=255,maxk=5005,inf=0x3f3f3f3f;  const ll llinf=0x3f3f3f3f3f3f3f3f;   const ld pi=acos(-1.0L);int head[maxn],current[maxn],dist[maxn],f[maxn];int up[maxk],down[maxk];int cnt[maxn][25];bool visit[maxn];int num;struct Edge {int from,to,pre,flow;};Edge edge[maxk*2];void addedge(int from,int to,int flow) {edge[num]=(Edge){from,to,head[from],flow};head[from]=num++;edge[num]=(Edge){to,from,head[to],0};head[to]=num++;}bool bfs(int n) {meminf(dist);mem0(visit);queue<int> q;q.push(0);dist[0]=0;visit[0]=1;while (!q.empty()) {int now=q.front();q.pop();for (int i=head[now];i!=-1;i=edge[i].pre) {int to=edge[i].to;if (!visit[to]&&edge[i].flow>0) q.push(to),dist[to]=dist[now]+1,visit[to]=1;}}return dist[n]!=inf;}int dfs(int now,int flow,int t) {if (now==t) return flow;for (int i=current[now];i!=-1;i=edge[i].pre) {int to=edge[i].to,f;current[now]=i;if (dist[to]==dist[now]+1&&edge[i].flow>0&&(f=dfs(to,min(flow,edge[i].flow),t))) {edge[i].flow-=f;edge[i^1].flow+=f;return f;}}return 0;}int dinic(int n) {int ans=0,f;while (bfs(n)) {memcpy(current,head,sizeof(current));while (f=dfs(0,inf,n)) ans+=f;}return ans;}int main() {int cas;scanf("%d",&cas);while (cas--) {int n,m,i,j,k,q,x,y,d,l=0;char c;scanf("%d%d",&n,&m);num=0;memset(head,-1,sizeof(head));for (i=1;i<=n;i++) {for (j=1;j<=m;j++) {cnt[i][j]=l++;}}mem0(f);for (i=1;i<=n;i++) {scanf("%d",&x);//addedge(n+m+1,i,0);f[i]+=x;f[n+m+1]-=x;}for (i=1;i<=m;i++) {scanf("%d",&x);//addedge(i+n,n+m+2,0);f[i+n]-=x;f[m+n+2]+=x;}scanf("%d",&q);mem0(down);meminf(up);for (k=1;k<=q;k++) {scanf("%d %d %c %d",&x,&y,&c,&d);if (c=='>') d++;if (c=='<') d--;int lr,rr,lc,rc;if (x==0) lr=1,rr=n; else lr=rr=x;if (y==0) lc=1,rc=m; else lc=rc=y;for (i=lr;i<=rr;i++) {for (j=lc;j<=rc;j++) {if (c!='>') up[cnt[i][j]]=min(up[cnt[i][j]],d);if (c!='<') down[cnt[i][j]]=max(down[cnt[i][j]],d);}}}if (f[n+m+1]+f[n+m+2]!=0) {printf("IMPOSSIBLE\n\n");continue;}int flag=0;for (i=1;i<=n;i++) {for (j=1;j<=m;j++) {if (up[cnt[i][j]]<down[cnt[i][j]]) flag=1; else    addedge(i,j+n,up[cnt[i][j]]-down[cnt[i][j]]);f[j+n]+=down[cnt[i][j]];f[i]-=down[cnt[i][j]];}}if (flag) {printf("IMPOSSIBLE\n\n");continue;}for (i=1;i<=n+m+2;i++) {if (f[i]>0) addedge(0,i,f[i]);     else addedge(i,n+m+3,-f[i]);}addedge(n+m+2,n+m+1,inf);/*for (i=0;i<num;i+=2) {cout << edge[i].from << ' ' << edge[i].to << ' ' << edge[i].flow << endl;}*/int s=0;for (i=head[0];i!=-1;i=edge[i].pre) {s+=edge[i].flow;}int ans=dinic(n+m+3);if (ans!=s) {printf("IMPOSSIBLE\n\n");continue;}for (i=1;i<=n;i++) {for (j=1;j<=m;j++) {printf("%d ",edge[cnt[i][j]*2+1].flow+down[cnt[i][j]]);}printf("\n");}printf("\n");}return 0;}



原创粉丝点击