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省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...
随机推荐
- Java,AWTUtilities,eclipse报编译错误:Access restriction: The type 'AWTUtilities' is not API (restriction on required library 'C:\Program Files\Java\jre7\lib\rt.jar')
[场景]调用com.sun.awt.AWTUtilities时,eclipse提示编译错误: Access restriction: The type 'AWTUtilities' is not AP ...
- 01_hello world
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 用crash来分析一下proc的文件访问
一般来说,用户通过fd的传入,调用open系统调用,来获取fd,然后read的时候,通过这个fd来查找对应的file* SYSCALL_DEFINE3(open, const char __user ...
- Pronunciation – The Definitive Guide to the Top 100 Words in American English
Pronunciation – The Definitive Guide to the Top 100 Words in American English Share Tweet Share Tagg ...
- 在Virtualenv中使用Idle
原创 在Virtualenv中使用Idle 本文适用于Linux系统,在DebianTesting上测试通过. 关于Virtualenv 先看一段Virtualenv这货的官方介绍: virtuale ...
- adb INSTALL_FAILED_UPDATE_INCOMPATIBLE
今天用Eclipse运行项目时出错: LOG: [2018-05-09 14:16:19 - Module_Android_Demo] ------------------------------ [ ...
- 浅析SQL Server 中的SOS_SCHEDULER_YIELD类型的等待
本文出处:http://www.cnblogs.com/wy123/p/6856802.html 进程的状态转换 在说明SOS_SCHEDULER_YIELD等待之前,先简要介绍一下进程的状态(迷迷糊 ...
- Structs复习 OGNL
Dominmodel只有传 User.age 类似的这种Structs才能帮创建对象 Dominmodel User里必须有空的构造方法 OGNL:OBJECT GRAPHIC NAVAGATION ...
- Hibernate学习笔记2.4(Hibernate的Id生成策略)
通过设置告诉id该怎么设置. 1.通过xml方式 1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据 ...
- python技巧 显示对象的所有属性
python技巧 显示对象的所有属性for attr in dir(ad):... print attr+":"+str(getattr(ad,attr))