POJ 2396 Budget(有源汇上下界网络流)
Description
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
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.
Output
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
相加后得到答案
代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; const int maxn=1e5+;
const int maxm=2e5+;
const int INF=0x3f3f3f3f; int TO[maxm],CAP[maxm],NEXT[maxm],tote;
int FIR[maxn],gap[maxn],cur[maxn],d[maxn],q[];
int n,m,S,T; void add(int u,int v,int cap)
{
//printf("i=%d u=%d v=%d cap=%d\n",tote,u,v,cap);
TO[tote]=v;
CAP[tote]=cap;
NEXT[tote]=FIR[u];
FIR[u]=tote++; TO[tote]=u;
CAP[tote]=;
NEXT[tote]=FIR[v];
FIR[v]=tote++;
}
void bfs()
{
memset(gap,,sizeof gap);
memset(d,,sizeof d);
++gap[d[T]=];
for(int i=;i<=n;++i)cur[i]=FIR[i];
int head=,tail=;
q[]=T;
while(head<=tail)
{
int u=q[head++];
for(int v=FIR[u];v!=-;v=NEXT[v])
if(!d[TO[v]])
++gap[d[TO[v]]=d[u]+],q[++tail]=TO[v];
}
}
int dfs(int u,int fl)
{
if(u==T)return fl;
int flow=;
for(int &v=cur[u];v!=-;v=NEXT[v])
if(CAP[v]&&d[u]==d[TO[v]]+)
{
int Min=dfs(TO[v],min(fl,CAP[v]));
flow+=Min,fl-=Min,CAP[v]-=Min,CAP[v^]+=Min;
if(!fl)return flow;
}
if(!(--gap[d[u]]))d[S]=n+;
++gap[++d[u]],cur[u]=FIR[u];
return flow;
}
int ISAP()
{
bfs();
int ret=;
while(d[S]<=n)ret+=dfs(S,INF);
return ret;
} int ca,N,M,Q,x,y,z,l[][],r[][];
char op[]; void init()
{
tote=;
memset(FIR,-,sizeof FIR);
memset(l,,sizeof l);
memset(r,INF,sizeof r);
}
void update(int x,int y)
{
if(op[]=='>')l[x][y]=max(l[x][y],z+);
else if(op[]=='=')l[x][y]=max(l[x][y],z),r[x][y]=min(r[x][y],z);
else if(op[]=='<')r[x][y]=min(r[x][y],z-);
}
bool build()
{
init();
scanf("%d%d",&N,&M);
int s=N+M+,t=N+M+;
int in[]={},sum=,sum1=;
add(t,s,INF);
S=N+M+,T=N+M+,n=T;
for(int i=;i<=N;i++)
scanf("%d",&x),add(s,T,x),in[i]+=x,in[s]-=x,sum+=x;
for(int i=;i<=M;i++)
scanf("%d",&x),add(S,t,x),in[i+N]-=x,in[t]+=x,sum1+=x;
scanf("%d",&Q);
for(int i=;i<=Q;i++)
{
scanf("%d%d%s%d",&x,&y,op,&z);
if(!x&&!y)
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
update(i,j);
else if(!x)
for(int i=;i<=N;i++)
update(i,y);
else if(!y)
for(int i=;i<=M;i++)
update(x,i);
else
update(x,y);
}
if(sum!=sum1)return ;
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
{
if(l[i][j]>r[i][j])return ;
add(i,j+N,r[i][j]-l[i][j]);
in[i]-=l[i][j];
in[j+N]+=l[i][j];
}
for(int i=;i<=N+M+;i++)
if(in[i]>)
{
add(S,i,in[i]);
sum+=in[i];
}
else
add(i,T,-in[i]);
return sum==ISAP();
}
int main()
{
int _;
scanf("%d",&_);
for(ca=;ca<_;ca++)
{
if(ca)printf("\n");
if(!build())printf("IMPOSSIBLE\n");
else
{
int out[][];
for(int i=;i<=N;i++)
for(int j=FIR[i];j!=-;j=NEXT[j])
if(N<TO[j]&&TO[j]<=N+M)
out[i][TO[j]-N]=CAP[j^];
for(int i=;i<=N;i++)
for(int j=;j<=M;j++)
printf("%d%c",out[i][j]+l[i][j],j==M?'\n':' ');
}
}
return ;
}
POJ 2396 Budget(有源汇上下界网络流)的更多相关文章
- ACM-ICPC 2018 沈阳赛区网络预赛 F. Fantastic Graph (贪心或有源汇上下界网络流)
"Oh, There is a bipartite graph.""Make it Fantastic."X wants to check whether a ...
- POJ2396 Budget [有源汇上下界可行流]
POJ2396 Budget 题意:n*m的非负整数矩阵,给出每行每列的和,以及一些约束关系x,y,>=<,val,表示格子(x,y)的值与val的关系,0代表整行/列都有这个关系,求判断 ...
- poj2396 Budget&&ZOJ1994 Budget[有源汇上下界可行流]
Budget Time Limit: 5 Seconds Memory Limit: 32768 KB Special Judge We are supposed to make ...
- ACM-ICPC 2018 沈阳赛区网络预赛 F Fantastic Graph(贪心或有源汇上下界网络流)
https://nanti.jisuanke.com/t/31447 题意 一个二分图,左边N个点,右边M个点,中间K条边,问你是否可以删掉边使得所有点的度数在[L,R]之间 分析 最大流不太会.. ...
- POJ 2396 Budget (有源汇有上下界最大流)
题意:给定一个矩阵的每行的和和每列的和,以及每个格子的限制,让你求出原矩阵. 析:把行看成X,列看成Y,其实就是二分图,然后每个X到每个Y边一条边,然后加一个超级源点和汇点分别向X和Y连边,这样就形成 ...
- poj 2396 Budget【有上下界的网络流】
第一步:建立无源汇有上下界的网络模型 每行 i 作为一个点并连边(s, i, Ri, Ri),每列 j 作为一个点并连边(j, t, Cj, Cj),设 Uij, Lij 分别表示第 i 行第 j 列 ...
- 【hihocoder 1424】 Asa's Chess Problem(有源汇上下界网络流)
UVALive-7670 ICPC北京2016-C题 hihocoder 1424 题意 有个 \(N\times N\) 的棋盘,告诉你每个格子黑色(1)或白色(0),以及每对能相互交换的同行或同列 ...
- 【Loj117】有源汇上下界最小流(网络流)
[Loj117]有源汇上下界最小流(网络流) 题面 Loj 题解 还是模板题. #include<iostream> #include<cstdio> #include< ...
- BZOJ_2502_清理雪道_有源汇上下界最小流
BZOJ_2502_清理雪道_有源汇上下界最小流 Description 滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...
随机推荐
- 更改html代码后网页不更新
写了一个非常简单的 html 页面,只有简单的跳转功能,但是在 Eclipse 下更改代码后用 chrome 浏览器打开时还是显示原来的网页.开始我以为是网页有错误或者有不规范的地方,因为我编写的是 ...
- 【动态规划】最大子段和问题,最大子矩阵和问题,最大m子段和问题
http://blog.csdn.net/liufeng_king/article/details/8632430 1.最大子段和问题 问题定义:对于给定序列a1,a2,a3……an,寻找它 ...
- 5分钟K线图压力线买点怎么看?
某开盘后底开一直呈现形成了一个长时间的箱体振荡的走势,K线在底位振荡时,其波动底点总是在不断抬高的话,这种走势说明有资金在场中积极运作,正是由于资金悄然建仓导致了底点慢慢抬高的走势,在底点不断抬高时, ...
- eclipse 连接数据库记录
两篇很好的文章介绍给大家: Eclipse使用JDBC方式连接SQLServer2016 通过Driver与DriverManager连接数据库 --------------------------- ...
- mysql 存储过程小问题
mysql写的存储过程的一些小问题 DELIMITER $$ USE `yzhoteldb`$$ DROP PROCEDURE IF EXISTS `yz_waveData`$$ CREATE DEF ...
- C# 基础 new 、override实现多台区别
一.new只是隐藏父类中的同名方法.基类和父类中都存在这个方法. namespace ConsoleApplication1 { class Program { static void Main(st ...
- redmine安装-BitNami 提供的一键安装程序
redmine安装-BitNami 提供的一键安装程序 博客分类: REDMINE redmine安装redmine一键安装bitNami redmine BitNami 提供re ...
- shiro 认证思路
- EF 数据迁移
数据迁移: 在程序包管理器控制台,执行语句. 初始化: 1.Enable-Migrations -EnableAutomaticMigrations 2.Add-Migration InitialCr ...
- Linux初学时的一些常用命令(1)
查看帮助: man 命令 退出帮助目录: q 切换目录:cd cd 目录 cd 目录/目录 cd .. :上一级目录 cd / :根目录cd ~ :回家 创建目录和删除目录 mkdi ...