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省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...
随机推荐
- crontab 安装与配置
安装方法: yum -y install vixie-cron yum -y install crontabs 说明:vixie-cron 软件包是 cron 的主程序:crontabs 软件包是用来 ...
- es6新特性之箭头函数
<script> { // es3,es5 var evens = [1, 2, 3, 4, 5]; var odds = evens.map(function (v) { return ...
- FormData上传文件(不是所有的浏览器都支持)
<h1>Ajax上传文件</h1> <div> <input type="file" id="img"/> &l ...
- vue.js 组件引用之初级 之二
1. template 标签也可以实现替换,这样可以省去script标签了 <!DOCTYPE html> <html lang="en"> <hea ...
- Delphi的程序单元、结构、基础知识(转)
Object Passal的程序结构很特殊,与其它语言如C++,Object Windows等结构都不同.一个Delphi程序由多个称为单元的源代码模块组成.使用单元可以把一个大型程序分成多个逻辑相关 ...
- 红警2在Y460和win10下运行
1.将电源模式改为高性能模式 2.以WinXP兼容模式运行 3.修改RA2.ini文件 在[Video]下加入以下代码 : AllowHiResModes=yes VideoBackBuffer=no ...
- 【358】GitHub 上面文件夹下载方法
参考:https://www.bilibili.com/read/cv210500/ 参考:https://www.jianshu.com/p/743ecc20ffb2 软件下载:Downloads ...
- userdel删除用户失败提示:userdel: user * is currently logged in 解决方法
操作环境 SuSE10/SuSE11 问题现象 执行userdel -rf oracle删除用户失败,提示userdel: user 'oracle' is currently logged in ...
- ajaxfileupload.js上传文件兼容IE7及以上版本
要兼容IE789,要修改ajaxfileupload.js;要将此处的代码替换掉 if(window.ActiveXObject) { var io = document.createElement( ...
- Ldap-crack-test?
ldap #!/bin/env python import sys import ldap ldapconn = ldap.initialize('ldap://domain.adserve.com' ...