一个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. python 原生态调用server服务————SimpleHTTPServer

    python 原生态调用server服务,接收http传递的参数并且处理返回结果 很多blog中都是抄了官网的,没有说明参数如何接收 1.代码中提供了post与get两种方式来发起请求,但是传递参数时 ...

  2. js给节点添加或删除类名

    为 <div> 元素添加 class: document.getElementById(“myDIV”).classList.add(“mystyle”); 为 <div> 元 ...

  3. 11.16 Daily Scrum

    由于今天是工作小周期的最后一天,今天的主要任务是解决了一周留下的技术方面的难题.一些类似于悬浮窗和进度条的bug修复全部在今天得到了解决,修复了数据库的内存泄露bug,软件的搜索功能的完善也接近尾声. ...

  4. Daily Scrum6 11.10

    今日任务: 徐钧鸿:codingcook的sql相关内容,并在进行复查张艺:继续用户管理部分代码黄可嵩:学习搜索的知识,继续进行搜索的移植和响应徐方宇:动态控件和页面间信息传递以及页面响应事件机制试验 ...

  5. magic mouse 2 使用,移动速度问题,安装问题

    一.安装问题 首先确保你的OSX里面没有安装USB Overdrive.prefPane这个软件,就是“瑞士军刀”.这个软件会让你的magic mouse 2 连接上Mac后,Mac无限死机重启,有时 ...

  6. CMD命令操作符

    cmd                   command的缩写,是windows环境下的虚拟DOS窗口,提供有DOS命令,功能强大 mstsc                 远程 inetmgr  ...

  7. 工作中常用到的Linux命令

    ps: (ps的参数分成basic, list, output, thread, miscellaneous) (basic) -e / -A 显示所有进程 (output) -o 输出指定字段 ls ...

  8. NodeJs 遍历文件夹内容 上传到服务器.并输出上传记录文件

    var path = require('path'); var glob = require('glob') var fs = require('fs'); var Promise = require ...

  9. 检测web服务器指定位置大文件是否存在

    在bugscan群里看到有人问有一个大文件,想探测其是否存在.如果使用curl的话,会将整个文件下载到节点,对于扫描没有任何用处,反而浪费了扫描时间. 于是我想到的解决办法是不使用curl,直接用底层 ...

  10. JVM内存管理机制

    Java与C++之间有一堆由内存动态分配与垃圾收集技术所围成的“高墙”,墙外面的人想进去,墙里面的人却想出来. —— <深入理解Java虚拟机:JVM高级特性与最佳实践> Java虚拟机在 ...