POJ 2396 Budget(有源汇上下界网络流)
Posted taozi1115402474
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2396 Budget(有源汇上下界网络流)相关的知识,希望对你有一定的参考价值。
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.
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.
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
2 2 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
题意
给你N行和和M行列,再给你一堆约束条件,问你是否存在N*M的矩阵满足条件
题解
有源汇上下界网络流经典题
这类题通常是从建完图发现源点s流出到汇点t流量,然后有些边有上下界条件
做法是把汇点连边流向源点流量为INF,让它变成一个循环流
然后就变成了无源汇上下界网络流问题,新建超级源点S,超级汇点T
令Mi=点总流入-点总流出
如果Mi>0,说明该点需要流出Mi流量,则建边S->i流量Mi
如果Mi<0,说明该点需要流入Mi流量,则建边i->T流量Mi
跑一边S->T的最大流求出一个可行流,可以得到每条边的流量,再加上下界就是答案
比如样例
2 2
2 2
2 2
2
0 0 > 1
0 0 < 10
建完图发现是N*M的矩阵
0 3 0
3 3 3
跑完最大流得到可行流
2 0 3
0 0 1
相加后得到答案
代码
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 const int maxn=1e5+5; 7 const int maxm=2e5+5; 8 const int INF=0x3f3f3f3f; 9 10 int TO[maxm],CAP[maxm],NEXT[maxm],tote; 11 int FIR[maxn],gap[maxn],cur[maxn],d[maxn],q[400000]; 12 int n,m,S,T; 13 14 void add(int u,int v,int cap) 15 { 16 //printf("i=%d u=%d v=%d cap=%d ",tote,u,v,cap); 17 TO[tote]=v; 18 CAP[tote]=cap; 19 NEXT[tote]=FIR[u]; 20 FIR[u]=tote++; 21 22 TO[tote]=u; 23 CAP[tote]=0; 24 NEXT[tote]=FIR[v]; 25 FIR[v]=tote++; 26 } 27 void bfs() 28 { 29 memset(gap,0,sizeof gap); 30 memset(d,0,sizeof d); 31 ++gap[d[T]=1]; 32 for(int i=1;i<=n;++i)cur[i]=FIR[i]; 33 int head=1,tail=1; 34 q[1]=T; 35 while(head<=tail) 36 { 37 int u=q[head++]; 38 for(int v=FIR[u];v!=-1;v=NEXT[v]) 39 if(!d[TO[v]]) 40 ++gap[d[TO[v]]=d[u]+1],q[++tail]=TO[v]; 41 } 42 } 43 int dfs(int u,int fl) 44 { 45 if(u==T)return fl; 46 int flow=0; 47 for(int &v=cur[u];v!=-1;v=NEXT[v]) 48 if(CAP[v]&&d[u]==d[TO[v]]+1) 49 { 50 int Min=dfs(TO[v],min(fl,CAP[v])); 51 flow+=Min,fl-=Min,CAP[v]-=Min,CAP[v^1]+=Min; 52 if(!fl)return flow; 53 } 54 if(!(--gap[d[u]]))d[S]=n+1; 55 ++gap[++d[u]],cur[u]=FIR[u]; 56 return flow; 57 } 58 int ISAP() 59 { 60 bfs(); 61 int ret=0; 62 while(d[S]<=n)ret+=dfs(S,INF); 63 return ret; 64 } 65 66 int ca,N,M,Q,x,y,z,l[205][25],r[205][25]; 67 char op[2]; 68 69 void init() 70 { 71 tote=0; 72 memset(FIR,-1,sizeof FIR); 73 memset(l,0,sizeof l); 74 memset(r,INF,sizeof r); 75 } 76 void update(int x,int y) 77 { 78 if(op[0]==‘>‘)l[x][y]=max(l[x][y],z+1); 79 else if(op[0]==‘=‘)l[x][y]=max(l[x][y],z),r[x][y]=min(r[x][y],z); 80 else if(op[0]==‘<‘)r[x][y]=min(r[x][y],z-1); 81 } 82 bool build() 83 { 84 init(); 85 scanf("%d%d",&N,&M); 86 int s=N+M+1,t=N+M+2; 87 int in[250]={0},sum=0,sum1=0; 88 add(t,s,INF); 89 S=N+M+3,T=N+M+4,n=T; 90 for(int i=1;i<=N;i++) 91 scanf("%d",&x),add(s,T,x),in[i]+=x,in[s]-=x,sum+=x; 92 for(int i=1;i<=M;i++) 93 scanf("%d",&x),add(S,t,x),in[i+N]-=x,in[t]+=x,sum1+=x; 94 scanf("%d",&Q); 95 for(int i=1;i<=Q;i++) 96 { 97 scanf("%d%d%s%d",&x,&y,op,&z); 98 if(!x&&!y) 99 for(int i=1;i<=N;i++) 100 for(int j=1;j<=M;j++) 101 update(i,j); 102 else if(!x) 103 for(int i=1;i<=N;i++) 104 update(i,y); 105 else if(!y) 106 for(int i=1;i<=M;i++) 107 update(x,i); 108 else 109 update(x,y); 110 } 111 if(sum!=sum1)return 0; 112 for(int i=1;i<=N;i++) 113 for(int j=1;j<=M;j++) 114 { 115 if(l[i][j]>r[i][j])return 0; 116 add(i,j+N,r[i][j]-l[i][j]); 117 in[i]-=l[i][j]; 118 in[j+N]+=l[i][j]; 119 } 120 for(int i=1;i<=N+M+2;i++) 121 if(in[i]>0) 122 { 123 add(S,i,in[i]); 124 sum+=in[i]; 125 } 126 else 127 add(i,T,-in[i]); 128 return sum==ISAP(); 129 } 130 int main() 131 { 132 int _; 133 scanf("%d",&_); 134 for(ca=0;ca<_;ca++) 135 { 136 if(ca)printf(" "); 137 if(!build())printf("IMPOSSIBLE "); 138 else 139 { 140 int out[205][25]; 141 for(int i=1;i<=N;i++) 142 for(int j=FIR[i];j!=-1;j=NEXT[j]) 143 if(N<TO[j]&&TO[j]<=N+M) 144 out[i][TO[j]-N]=CAP[j^1]; 145 for(int i=1;i<=N;i++) 146 for(int j=1;j<=M;j++) 147 printf("%d%c",out[i][j]+l[i][j],j==M?‘ ‘:‘ ‘); 148 } 149 } 150 return 0; 151 }
以上是关于POJ 2396 Budget(有源汇上下界网络流)的主要内容,如果未能解决你的问题,请参考以下文章