一个m行n列的矩阵,给出每行每列中元素的和,以及对一些格子的大小限制,求一个可行方案,输出矩阵。

大小限制形如:严格大于i,严格小于i,等于i。

1<=m<=200.1<=n<=20.

有源汇上下界可行流。

将每一行作为一个点,每一列作为一个点。

源点向每个行点连一条上下界均为该行和的边。

每个列点向汇点连一条上下界均为该列和的边。

每个行点向各列点连一条上下界为该行该列对应点的上下限的边。

然后做一遍有源汇上下界可行流就好了。

(汇点向源点连一条上界为正无穷下界为0的边,就转成无源汇上下界可行流啦!

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int dian=;
const int bian=;
const int INF=0x3f3f3f3f;
int h[dian],nxt[bian],ver[bian],val[bian],ch[dian],cr[dian];
int sx[][],xx[][],bh[][],in[dian],out[dian];
int n,m,aa,bb,cc,tot,num,flag,summ;
int S,T,SS,TT;
char la[];
void add(int a,int b,int c,int d){
tot++;ver[tot]=b;val[tot]=d-c;nxt[tot]=h[a];h[a]=tot;
tot++;ver[tot]=a;val[tot]=;nxt[tot]=h[b];h[b]=tot;
in[b]+=c;
out[a]+=c;
}
bool tell(){
memset(ch,-,sizeof(ch));
queue<int>q;
q.push(S);
ch[S]=;
while(!q.empty()){
int t=q.front();
q.pop();
for(int i=h[t];i;i=nxt[i])
if(ch[ver[i]]==-&&val[i]){
ch[ver[i]]=ch[t]+;
q.push(ver[i]);
}
}
return ch[T]!=-;
}
int zeng(int a,int b){
if(a==T)
return b;
int r=;
for(int i=cr[a];i&&b>r;i=nxt[i])
if(ch[ver[i]]==ch[a]+&&val[i]){
int t=zeng(ver[i],min(b-r,val[i]));
val[i]-=t,r+=t,val[i^]+=t;
if(val[i])
cr[a]=i;
}
if(!r)
ch[a]=-;
return r;
}
int dinic(){
int r=,t;
while(tell()){
for(int i=;i<=n+m+;i++)
cr[i]=h[i];
while(t=zeng(S,INF))
r+=t;
}
return r;
}
int main(){
int cas;
scanf("%d",&cas);
while(cas--){
memset(h,,sizeof(h));
memset(nxt,,sizeof(nxt));
memset(sx,0x3f,sizeof(sx));
memset(xx,,sizeof(xx));
memset(in,,sizeof(in));
memset(out,,sizeof(out));
tot=;
summ=;
scanf("%d%d",&n,&m);
SS=n+m+,TT=n+m+,S=n+m+,T=n+m+;
for(int i=;i<=n;i++){
scanf("%d",&aa);
add(SS,i,aa,aa);
}
for(int i=;i<=m;i++){
scanf("%d",&aa);
add(n+i,TT,aa,aa);
}
scanf("%d",&num);
while(num--){
scanf("%d%d%s%d",&aa,&bb,la,&cc);
if(!aa&&!bb){
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
if(la[]=='<')
sx[i][j]=min(sx[i][j],cc-);
else if(la[]=='>')
xx[i][j]=max(xx[i][j],cc+);
else{
sx[i][j]=min(sx[i][j],cc);
xx[i][j]=max(xx[i][j],cc);
}
}
}
else if(!aa){
for(int i=;i<=n;i++){
if(la[]=='<')
sx[i][bb]=min(sx[i][bb],cc-);
else if(la[]=='>')
xx[i][bb]=max(xx[i][bb],cc+);
else{
sx[i][bb]=min(sx[i][bb],cc);
xx[i][bb]=max(xx[i][bb],cc);
}
}
}
else if(!bb){
for(int i=;i<=m;i++){
if(la[]=='<')
sx[aa][i]=min(sx[aa][i],cc-);
else if(la[]=='>')
xx[aa][i]=max(xx[aa][i],cc+);
else{
sx[aa][i]=min(sx[aa][i],cc);
xx[aa][i]=max(xx[aa][i],cc);
}
}
for(int i=;i<=n;i++){
if(la[]=='<')
sx[i][bb]=min(sx[i][bb],cc-);
else if(la[]=='>')
xx[i][bb]=max(xx[i][bb],cc+);
else{
sx[i][bb]=min(sx[i][bb],cc);
xx[i][bb]=max(xx[i][bb],cc);
}
}
}
else{
if(la[]=='<')
sx[aa][bb]=min(sx[aa][bb],cc-);
else if(la[]=='>')
xx[aa][bb]=max(xx[aa][bb],cc+);
else{
sx[aa][bb]=min(sx[aa][bb],cc);
xx[aa][bb]=max(xx[aa][bb],cc);
}
}
}
flag=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(sx[i][j]>=xx[i][j]){
bh[i][j]=tot+;
add(i,n+j,xx[i][j],sx[i][j]);
}
else{
flag=;
break;
}
}
if(flag)
break;
}
if(flag){
puts("IMPOSSIBLE");
puts("");
continue;
}
add(TT,SS,,INF);
for(int i=;i<=TT;i++){
if(in[i]-out[i]>)
add(S,i,,in[i]-out[i]);
else if(out[i]-in[i]>){
add(i,T,,out[i]-in[i]);
summ=summ+out[i]-in[i];
}
}
if(dinic()!=summ){
puts("IMPOSSIBLE");
puts("");
continue;
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++)
printf("%d ",xx[i][j]+val[bh[i][j]^]);
puts("");
}
puts("");
}
return ;
}

注意:

一个格子可能有多重限制,上限取min下限取max。

上限可能小于下限要判掉。

每组数据输出间有空行(不加也没事?)。

如果wa了就再读一遍建图,不行就再读一遍。

poj 2396 Budget的更多相关文章

  1. POJ 2396 Budget 有上下界的网络流

    POJ 2396  Budget 题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测.矩阵规模小于200*20. 网络流的模型是显而易见的,不过对 ...

  2. poj 2396 Budget 边容量有上下界的最大流

    题意: 给一个矩阵的每行和及每列和,在给一些行列或点的限制条件.求一个满足的矩阵. 分析: 转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法. 代码: //poj 2396 / ...

  3. POJ 2396 Budget(有源汇上下界网络流)

    Description We are supposed to make a budget proposal for this multi-site competition. The budget pr ...

  4. POJ 2396 Budget【网络流】

    题意: cas           //测试数据组数 n m         //行数 列数 a1 a2 ... an    //每行的和 b1 b2 ... bn   //每列的和 q       ...

  5. POJ 2396 Budget (有源汇有上下界最大流)

    题意:给定一个矩阵的每行的和和每列的和,以及每个格子的限制,让你求出原矩阵. 析:把行看成X,列看成Y,其实就是二分图,然后每个X到每个Y边一条边,然后加一个超级源点和汇点分别向X和Y连边,这样就形成 ...

  6. POJ 2396 Budget ——有上下界的网络流

    给定矩阵的每行每列的和,和一些大于小于等于的限制.然后需要求出一组可行解. 上下界网络流. 大概的思想就是计算出每一个点他需要强行流入或者流出的量,然后建出超级源点和汇点,然后删除下界,就可以判断是否 ...

  7. poj 2396 Budget【有上下界的网络流】

    第一步:建立无源汇有上下界的网络模型 每行 i 作为一个点并连边(s, i, Ri, Ri),每列 j 作为一个点并连边(j, t, Cj, Cj),设 Uij, Lij 分别表示第 i 行第 j 列 ...

  8. POJ 2396 Budget (上下界网络流有源可行流)

    转载: http://blog.csdn.net/axuan_k/article/details/47297395 题目描述: 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表 ...

  9. [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流

    poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...

随机推荐

  1. HTTP-HTTPS区别

    超文本传输协议HTTP协议被用于在Web浏览器和网站服务器之间传递信息,HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂 ...

  2. 转载----C/C++ 中 const 修饰符用法总结

    感谢原创作者,写的好详细.不忍错过,所以转载过来了... 原文地址: https://www.cnblogs.com/icemoon1987/p/3320326.html 在这篇文章中,我总结了一些C ...

  3. 学习Mybatis的两个必须的jar包分享

    百度云盘:http://pan.baidu.com/s/1nuNxRcd 提取码:t765(好像不需要提取码,不太会用云盘...) 自己学习mybatis的时候去找这两个jar包也是不容易,特别分享一 ...

  4. HDU 1003 最大连续子段和

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1003 Max Sum Time Limit: 2000/1000 MS (Java/Others)M ...

  5. 团队作业5-Alpha版本测试报告

    1.在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? 修复的Bug: a. 修复的bug: 页面打开后比例改变: 出现中文乱码: 点击按钮时不能响应: 导航栏加入显示错误: 上传图片后 ...

  6. __weak与__block修饰符区别

    API Reference对__block变量修饰符的解释,大概意思: 1.__block对象在block中是可以被修改.重新赋值的. 2.__block对象在block中不会被block强引用一次, ...

  7. 微信小程序配置文件记录

    最近公司要求,需要研究微信方面的问题,我有幸被选中了,一周时间,研究透做出个小程序来.我就从简单的开始了,记录一下,以后忘了,好来翻阅 app.json 配置文件 配置文件上写:是由哪些页面组成,配置 ...

  8. 配置ssh免密码登入

    首先要设置好主机名hostnamectl,然后编辑文件/etc/hosts 192.168.43.9 node0 192.168.43.10 node1 192.168.43.11 node2     ...

  9. Spring 2.0

    ProductBacklog:继续向下细化; 1.界面美化,统一界面风格,以简洁美观为主: 2.丰富版面的内容,吸引用户: 3.尝试增加新的版面: Sprint 计划会议:确定此次冲刺要完成的目标 1 ...

  10. build.xml

    下载ant 解压ant 后设置ANT_HOME, PATH中添加ANT_HOME目录下的bin目录(如:ANT_HOME:,PATH:D:\apache-ant-1.9.2%ANT_HOME%\bin ...