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省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道), ...
随机推荐
- 机器学习入门-文本数据-构造词频词袋模型 1.re.sub(进行字符串的替换) 2.nltk.corpus.stopwords.words(获得停用词表) 3.nltk.WordPunctTokenizer(对字符串进行分词操作) 4.np.vectorize(对函数进行向量化) 5. CountVectorizer(构建词频的词袋模型)
函数说明: 1. re.sub(r'[^a-zA-Z0-9\s]', repl='', sting=string) 用于进行字符串的替换,这里我们用来去除标点符号 参数说明:r'[^a-zA-Z0- ...
- ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql/mysql.sock' (2)
[root@XXX ~]# mysql -h localhost -uroot -p Enter password: ERROR (HY000): Can't connect to local MyS ...
- mui集成百度ECharts的统计图表以及清空释放图表
echarts官网地址: http://echarts.baidu.com/index.html 更换主题颜色: // 图表清空------------------- mychart.clear(); ...
- zookeeper windows7下集群搭建
模拟分布式环境!!! 搞了好几天,各种错误!!终于成功了. 环境: windows7 /centos/xsheel 安装了三个虚拟机... 1.下载zookeeper http://archi ...
- World Cup 996B(排队模拟)
题意:有n个通道,按顺序每一次站一个通道,直到所站的通道没有人 分析:模拟这个过程 #include<cstdio> int main() { ]; while(~scanf(" ...
- 【转】 DOTA2中的伪随机及其lua实现
因为单纯的随机确实会影响到竞技性,所以dota2引入的是伪随机机制,在大量的技能中,比如说混沌的混乱之箭.剑圣的剑舞.冰女的冰霜领域之类的技能,都利用了伪随机机制. 而纯随机,或者标准正态分布并不会因 ...
- C#调用C++
c++ extern "C" __declspec(dllexport) char* WINAPI base64_decode( char *data,char base[]) { ...
- python pip 下载慢 配置使用国内源配置
ubuntu apt 使用国内源 设置>软件和更新>下载自 选择mirrors.aliyun.com/ubuntu 更新源sudo apt-get update 安装系统包:sudo ap ...
- Celery 图,[转]
https://www.cnblogs.com/forward-wang/p/5970806.html
- C++ 关于MFC List Control 控件的使用事项 原创
1\在开发项目时,使用到了 listcontrol 控件,就一些问题,做一下备注,以备以后使用 (1) 给list项目 删除所有的项目 DeleteAllItems(); (2) 给list项目 ...