题意:

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

分析:

转化为有上下界的网络流,注意等于也是一种上下界关系,然后用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. hdoj--1533--Going Home(KM)

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Tota ...

  2. [ligerUI] grid封装调用方法

    /** * 获取页面参数 */ function getPageSize(){ var xScroll, yScroll; if (window.innerHeight && wind ...

  3. Ubuntu16.04下将hadoop2.7.3源代码导入到eclipse neon中

    0.为什么会有这篇: 这篇文章的目的在于帮助想学习hadoop源码的内容,却在导入的过程中出现了各种问题的人. 或许你一定找了很多博客都无果,那么不用担心,我和你一样,这也是这篇文章存在的意义,废话少 ...

  4. Java Socket通讯---网络基础

    java socket 通讯 参考慕课网:http://www.imooc.com/learn/161 一.网络基础知识 1.1 通讯示意图 1.2 TCP/IP协议 TCP/IP是世界上应用最为广泛 ...

  5. python学习-字符串 列表 元祖

    目录 Python翻转字符串(reverse string) 简单的步长为-1, 即字符串的翻转(常用) 递归反转 借用列表,使用reverse()方法 字符串常用操作 index split 切片 ...

  6. Oracle性能优化——总体介绍

    最近参加Oracle的培训,对Oracle有了更加深入的认识,在此做个学习总结. 1.Oracle数据库调优不能仅指望修改几项数据库参数就能有明显效果,问题更多出在应用方面,教育开发者正确地使用数据库 ...

  7. 谷歌vimium配置

    谷歌不得不说真的是一个非常好用的浏览器(之前用的浏览器真的好low),推荐一款非常极客的的插件vimium,让你使用彻底告别鼠标,瞬间感觉高大上... 默认配置: j: 向下细微滚动窗口.  k:向上 ...

  8. [hihocoder][Offer收割]编程练习赛49

    相似颜色 #pragma comment(linker, "/STACK:102400000,102400000") #include<stdio.h> #includ ...

  9. 第一天:java与mysql的连接工具类

    第一天:java与mysql的连接工具类 java最新版马上就要收费,这无疑是这门语言的衰败起始,毕竟在中国收费便难发展,例如c#,但是毕业设计已经选好用java来写一个动态网站, 这已经是一个事实, ...

  10. NEFU 116 两仪剑法 【求最小公倍数】

    题目链接:http://acm.nefu.edu.cn/JudgeOnline/status.php?problem_id=116&order=1 解题思路:求最小公倍数 #include&l ...