题意:

给一个矩阵的每行和及每列和,在给一些行列或点的限制条件。求一个满足的矩阵。

分析:

转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法。

代码:

//poj 2396
//sep9
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int maxN=210;
const int maxM=40;
const int maxV=260;
const int maxE=26000;
struct Edge
{
int u,v,f,nxt;
}e[maxE*2+10];
queue<int> que;
int src,sink;
int g[maxV+10];
int nume;
bool vis[maxV+10];
int dist[maxV+10]; int N,M,low[maxN][maxM],high[maxN][maxM],ids[maxN][maxM],R[maxN],C[maxM];
int SS,TT;
void addedge(int u,int v,int c)
{
e[nume].u=u,e[nume].v=v;e[nume].f=c;e[nume].nxt=g[u];g[u]=nume++;
e[nume].u=v;e[nume].v=u;e[nume].f=0;e[nume].nxt=g[v];g[v]=nume++;
} void update(int x1,int x2,int y1,int y2,char op,int z)
{
for(int i=x1;i<=x2;++i)
for(int j=y1;j<=y2;++j){
if(op=='=')
low[i][j]=max(low[i][j],z),high[i][j]=min(high[i][j],z);
else if(op=='<')
high[i][j]=min(high[i][j],z-1);
else
low[i][j]=max(low[i][j],z+1);
}
}
int check()
{
for(int i=1;i<=N;++i)
for(int j=1;j<=M;++j)
if(low[i][j]>high[i][j])
return 0;
return 1;
}
void init()
{
memset(g,0,sizeof(g));
nume=2;
int i,j,k,x,y,z,c;
char op[16];
scanf("%d%d",&N,&M);
memset(low,0,sizeof(low)),memset(high,0x7f,sizeof(high));
for(i=1;i<=N;++i) scanf("%d",&R[i]);
for(i=1;i<=M;++i) scanf("%d",&C[i]);
scanf("%d",&c);
while(c--){
scanf("%d%d%s%d",&x,&y,op,&z);
if(x==0&&y==0) update(1,N,1,M,op[0],z);
else if(x==0) update(1,N,y,y,op[0],z);
else if(y==0) update(x,x,1,M,op[0],z);
else update(x,x,y,y,op[0],z);
}
} int bfs()
{
while(!que.empty()) que.pop();
memset(dist,0,sizeof(dist));
memset(vis,0,sizeof(vis));
vis[src]=true;
que.push(src);
while(!que.empty()){
int u=que.front();que.pop();
for(int i=g[u];i;i=e[i].nxt)
if(e[i].f&&!vis[e[i].v]){
que.push(e[i].v);
dist[e[i].v]=dist[u]+1;
vis[e[i].v]=true;
if(e[i].v==sink)
return 1;
}
}
return 0;
} int dfs(int u,int delta)
{
if(u==sink)
return delta;
int ret=0;
for(int i=g[u];ret<delta&&i;i=e[i].nxt)
if(e[i].f&&dist[e[i].v]==dist[u]+1){
int dd=dfs(e[i].v,min(e[i].f,delta-ret));
if(dd>0){
e[i].f-=dd;
e[i^1].f+=dd;
ret+=dd;
}
else
dist[e[i].v]=-1;
}
return ret;
} int dinic()
{
int ret=0;
while(bfs()==1)
ret+=dfs(src,INT_MAX);
return ret;
} int build()
{
int i,j,sum=0;
src=0,sink=N+M+1,SS=sink+1;TT=sink+2;
addedge(sink,src,INT_MAX);
for(i=1;i<=N;++i){
addedge(SS,i,R[i]);addedge(src,TT,R[i]);
sum+=R[i];
}
for(i=1;i<=M;++i){
addedge(SS,sink,C[i]);addedge(N+i,TT,C[i]);
sum+=C[i];
}
for(i=1;i<=N;++i)
for(j=1;j<=M;++j){
ids[i][j]=nume+1;
addedge(i,N+j,high[i][j]-low[i][j]);
addedge(SS,N+j,low[i][j]);
addedge(i,TT,low[i][j]);
sum+=low[i][j];
}
return sum;
} void solve()
{
if(!check()){
puts("IMPOSSIBLE");
return ;
}
int sum=build();
src=SS,sink=TT;
if(sum!=dinic())
puts("IMPOSSIBLE");
else{
for(int i=1;i<=N;++i){
for(int j=1;j<=M;++j)
printf("%d ",e[ids[i][j]].f+low[i][j]);
printf("\n");
}
}
} int main()
{
int cases;
scanf("%d",&cases);
while(cases--){
init();
solve();
printf("\n");
}
return 0;
}

poj 2396 Budget 边容量有上下界的最大流的更多相关文章

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

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

  2. POJ 2396 有源有汇有上下界可行流问题

    题意:给一个矩阵,给出每行每列之和,附加一些条件,如第i行第j列数必需大于(小于)多少. 思路题解:矩阵模型,模拟网络流,行.列标号为结点,构图,附加s,t,s连行标(容量上下限每行之和(必需以这个 ...

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

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

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

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

  5. ZOJ 2314 带上下界的可行流

    对于无源汇问题,方法有两种. 1 从边的角度来处理. 新建超级源汇, 对于每一条有下界的边,x->y, 建立有向边 超级源->y ,容量为x->y下界,建立有向边 x-> 超级 ...

  6. SGU 176.Flow construction (有上下界的最大流)

    时间限制:0.5s 空间限制:4M 题意: 有一个由管道组成的网络,有n个节点(n不大于100),1号节点可以制造原料,最后汇集到n号节点.原料通过管道运输.其中有一些节点有管道连接,这些管道都有着最 ...

  7. zoj3229 Shoot the Bullet(有源汇有上下界的最大流)

    题意: 一个屌丝给m个女神拍照,计划拍照n天,每一天屌丝给给定的C个女神拍照,每天拍照数不能超过D张,而且给每个女神i拍照有数量限制[Li,Ri],对于每个女神n天的拍照总和不能少于Gi,如果有解求屌 ...

  8. zoj 3229 有源汇有上下界的最大流模板题

    /*坑啊,pe的程序在zoj上原来是wa. 题目大意:一个屌丝给m个女神拍照.计划拍照n天,每一天屌丝最多个C个女神拍照,每天拍照数不能超过D张,并且给每一个女神i拍照有数量限制[Li,Ri], 对于 ...

  9. LOJ #116 有源汇点有上下界的最大流

    先连一条从汇点到源点的容量为INF的边,将其转化成无源汇点有上下界的可行流,判断是否可行 若可行的话删掉超级源点和超级汇点,再跑一遍最大流即可 #include <iostream> #i ...

随机推荐

  1. WinSocket聊天程序实例(多线程)

    #pragma comment(lib,"Ws2_32.lib") #include <stdio.h> #include <Winsock2.h> SOC ...

  2. Super超级ERP系统---(3)基础信息管理--商品管理

    商品管理主要包括商品的添加,修改,维护商品所在分类,单位,供应商,品牌,名称,价格,尺寸,规格等属性的维护.   1.商品添加 2.商品列表展示 商品列表界面左侧商品分类,右侧是商品信息

  3. Redis之Ubuntu下Redis集群搭建

    安装redis 首先下载redis $ wget http://download.redis.io/releases/redis-4.0.10.tar.gz $ .tar.gz $ cd redis- ...

  4. Android中使用GoogleMap的地理位置服务

    写在前面:android中使用地理位置功能,可以借助Google给我们提供的框架,要是有地理位置功能,你需要引用Google Play Services,请在sdk manager中下载.如果你还要使 ...

  5. XML DTD跟SCHEMA约束 语法了解

    dtd语法 元素: <!Element 元素名称 数据类型|包含内容> 数据类型: #PCDATA:普通文本 使用的时候一般用()引起来 包含内容: 该元素下可以出现哪些元素, 用()引起 ...

  6. 时间&物质&效率

    由于我的家庭是地道的农民家庭,在上学的时候,父母很辛苦的供我读初中,高中,大学. 现在我想说的是,用时间来换取效率是我求学时最大的遗憾. 举一个例子吧:每次回家坐火车,火车很费时间,假如我不缺钱,完全 ...

  7. [ Database ] [ SQL Server ] SQL Server 很多不允許的操作解決方法

    說明可參考 https://blog.miniasp.com/post/2012/10/26/SQL-Server-Management-Studio-Prevent-saving-changes-t ...

  8. 详解sqlserver查询表索引

    SELECT   索引名称=a.name ,表名=c.name ,索引字段名=d.name ,索引字段位置=d.colid ? 1 2 3 4 5 6 7 8 FROM  sysindexes  a ...

  9. SpringMVC(三)@PathVariable

    使用@PathVariable可以快速的访问,URL中的部分内容. ①. 在@RequestMapping的value中使用URI template({变量名}),然后在@RequestMapping ...

  10. springboot-注解讲解

    @Configuration:声明我们JdbcConfig是一个配置类 @PropertySource:指定属性文件的路径是:classpath:jdbc.properties 通过@Value为属性 ...