题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的。

经典的流量有上下界网络流问题。

  • 把行、列看成点,各单元看成边
  • 源点向各行连容量下界0上界该行和的边,各列向汇点连容量下界0上界该列和的边
  • 对于各单元,其对应行列表示的边间连下界上界和约束条件对应的边

这样就是求解这个网络的可行流,可以通过汇点向源点连容量INF的边,使各个顶点都满足平衡条件,这样转化成无源汇有上下界网络流来求解。

最后就是再转化一下求解无源汇有上下界网络流了,见ZOJ2314

要注意的是条件是负数的时候,要的是非负整数解,有些就直接是IMPOSSIBLE,而对于>-100这种情况是可以的,不过因为网络流的容量不能为负,这时把-100设置成0即可。

 #include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 444
#define MAXM 444*888 struct Edge{
int v,cap,flow,next;
}edge[MAXM];
int vs,vt,NE,NV;
int head[MAXN]; void addEdge(int u,int v,int cap){
edge[NE].v=v; edge[NE].cap=cap; edge[NE].flow=;
edge[NE].next=head[u]; head[u]=NE++;
edge[NE].v=u; edge[NE].cap=; edge[NE].flow=;
edge[NE].next=head[v]; head[v]=NE++;
} int level[MAXN];
int gap[MAXN];
void bfs(){
memset(level,-,sizeof(level));
memset(gap,,sizeof(gap));
level[vt]=;
gap[level[vt]]++;
queue<int> que;
que.push(vt);
while(!que.empty()){
int u=que.front(); que.pop();
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(level[v]!=-) continue;
level[v]=level[u]+;
gap[level[v]]++;
que.push(v);
}
}
} int pre[MAXN];
int cur[MAXN];
int ISAP(){
bfs();
memset(pre,-,sizeof(pre));
memcpy(cur,head,sizeof(head));
int u=pre[vs]=vs,flow=,aug=INF;
gap[]=NV;
while(level[vs]<NV){
bool flag=false;
for(int &i=cur[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[u]==level[v]+){
flag=true;
pre[v]=u;
u=v;
//aug=(aug==-1?edge[i].cap:min(aug,edge[i].cap));
aug=min(aug,edge[i].cap-edge[i].flow);
if(v==vt){
flow+=aug;
for(u=pre[v]; v!=vs; v=u,u=pre[u]){
edge[cur[u]].flow+=aug;
edge[cur[u]^].flow-=aug;
}
//aug=-1;
aug=INF;
}
break;
}
}
if(flag) continue;
int minlevel=NV;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(edge[i].cap!=edge[i].flow && level[v]<minlevel){
minlevel=level[v];
cur[u]=i;
}
}
if(--gap[level[u]]==) break;
level[u]=minlevel+;
gap[level[u]]++;
u=pre[u];
}
return flow;
}
int d[MAXN];
int low[MAXN][MAXN],up[MAXN][MAXN];
int main(){
int t,n,m,a,b,c;
char ch;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
memset(d,,sizeof(d));
int S=,T=n+m+;
vs=T+; vt=vs+; NV=vt+; NE=;
memset(head,-,sizeof(head));
addEdge(T,S,INF);
bool flag=;
for(int i=; i<=n; ++i){
scanf("%d",&a);
d[i]-=a;
if(a<) flag=;
}
for(int i=; i<=m; ++i){
scanf("%d",&a);
d[i+n]+=a;
if(a<) flag=;
}
for(int i=; i<=n; ++i){
for(int j=; j<=m; ++j){
low[i][j]=; up[i][j]=INF;
}
}
int k;
scanf("%d",&k);
while(k--){
scanf("%d%d",&a,&b); scanf(" %c",&ch); scanf("%d",&c);
if(ch=='>') ++c;
else if(ch=='<') --c;
if(ch=='<' && c<) flag=;
if(c<) c=;
if(a== && b==){
for(int i=; i<=n; ++i){
for(int j=; j<=m; ++j){
if(ch=='=') low[i][j]=up[i][j]=c;
else if(ch=='>') low[i][j]=c;
else up[i][j]=c;
}
}
}else if(a==){
for(int i=; i<=n; ++i){
if(ch=='=') low[i][b]=up[i][b]=c;
else if(ch=='>') low[i][b]=c;
else up[i][b]=c;
}
}else if(b==){
for(int i=; i<=m; ++i){
if(ch=='=') low[a][i]=up[a][i]=c;
else if(ch=='>') low[a][i]=c;
else up[a][i]=c;
}
}else{
if(ch=='=') low[a][b]=up[a][b]=c;
else if(ch=='>') low[a][b]=c;
else up[a][b]=c;
}
}
for(int i=; i<=n; ++i){
for(int j=; j<=m; ++j){
addEdge(i,j+n,up[i][j]-low[i][j]);
d[i]+=low[i][j];
d[j+n]-=low[i][j];
}
}
int tot=;
for(int i=S; i<=T; ++i){
if(d[i]<) addEdge(vs,i,-d[i]);
else addEdge(i,vt,d[i]),tot+=d[i];
}
if(flag || ISAP()!=tot){
puts("IMPOSSIBLE");
if(t) putchar('\n');
continue;
}
for(int u=; u<=n; ++u){
for(int i=head[u]; i!=-; i=edge[i].next){
if(i&) continue;
int v=edge[i].v;
low[u][v-n]+=edge[i].flow;
}
}
for(int i=; i<=n; ++i){
for(int j=; j<=m; ++j){
printf("%d ",low[i][j]);
}
putchar('\n');
}
if(t) putchar('\n');
}
return ;
}

POJ2396 Budget(有源汇流量有上下界网络的可行流)的更多相关文章

  1. HDU3157 Crazy Circuits(有源汇流量有上下界网络的最小流)

    题目大概给一个电路,电路上有n+2个结点,其中有两个分别是电源和负载,结点们由m个单向的部件相连,每个部件都有最少需要的电流,求使整个电路运转需要的最少电流. 容量网络的构建很容易,建好后就是一个有源 ...

  2. ZOJ3229 Shoot the Bullet(有源汇流量有上下界网络的最大流)

    题目大概说在n天里给m个女孩拍照,每个女孩至少要拍Gi张照片,每一天最多拍Dk张相片且都有Ck个拍照目标,每一个目标拍照的张数要在[Lki, Rki]范围内,问最多能拍几张照片. 源点-天-女孩-汇点 ...

  3. ZOJ2314 Reactor Cooling(无源汇流量有上下界网络的可行流)

    题目大概说一个核反应堆的冷却系统有n个结点,有m条单向的管子连接它们,管子内流量有上下界的要求,问能否使液体在整个系统中循环流动. 本质上就是求一个无源汇流量有上下界的容量网络的可行流,因为无源汇的容 ...

  4. zoj 3229 上下界网络最大可行流带输出方案

    收获: 1. 上下界网络流求最大流步骤: 1) 建出无环无汇的网络,并看是否存在可行流 2) 如果存在,那么以原来的源汇跑一次最大流 3) 流量下界加上当前网络每条边的流量就是最大可行流了. 2. 输 ...

  5. BZOJ 3876 支线剧情 有源汇有上下界最小费用可行流

    题意: 给定一张拓扑图,每条边有边权,每次只能从第一个点出发沿着拓扑图走一条路径,求遍历所有边所需要的最小边权和 分析: 这道题乍一看,可能会想到什么最小链覆盖之类的,但是仔细一想,会发现不行,一是因 ...

  6. hdu 4940 Destroy Transportation system( 无源汇上下界网络流的可行流推断 )

    题意:有n个点和m条有向边构成的网络.每条边有两个花费: d:毁坏这条边的花费 b:重建一条双向边的花费 寻找这样两个点集,使得点集s到点集t满足 毁坏全部S到T的路径的费用和 > 毁坏全部T到 ...

  7. BZOJ 2055 80人环游世界 有上下界最小费用可行流

    题意: 现在有这么一个m人的团伙,也想来一次环游世界. 他们打算兵分多路,游遍每一个国家.    因为他们主要分布在东方,所以他们只朝西方进军.设从东方到西方的每一个国家的编号依次为1...N.假若第 ...

  8. sgu 176 上下界网络流最小可行流带输出方案

    算法步骤: 1. 先将原图像最大可行流那样变换,唯一不同的是不加dst->src那条边来将它变成无源无汇的网络流图.直接跑一边超级源到超级汇的最大流. 2. 加上刚才没有加上的那条边p 3. 再 ...

  9. POJ2396 Budget [有源汇上下界可行流]

    POJ2396 Budget 题意:n*m的非负整数矩阵,给出每行每列的和,以及一些约束关系x,y,>=<,val,表示格子(x,y)的值与val的关系,0代表整行/列都有这个关系,求判断 ...

随机推荐

  1. PHP常量PHP_SAPI与函数php_sapi_name()简介,PHP运行环境检测

    php_sapi_name() 是用来检测PHP运行环境的函数. 该函数返回一个描述PHP与WEB服务器接口的小写字符串. 例如:aolserver, apache,apache2filter, ap ...

  2. java笔记--查看和修改线程名称

    查看和修改线程名称 --如果朋友您想转载本文章请注明转载地址"http://www.cnblogs.com/XHJT/p/3893797.html  "谢谢-- java是一种允许 ...

  3. HDU 4920 Matrix multiplication (硬件优化)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4920 解题报告:求两个800*800的矩阵的乘法. 参考这篇论文:http://wenku.baidu ...

  4. C++中new的解说

    new int;//开辟一个存放整数的存储空间,返回一个指向该存储空间的地址(即指针) new int(100);//开辟一个存放整数的空间,并指定该整数的初值为100,返回一个指向该存储空间的地址 ...

  5. cas单点注销失败Error Sending message to url endpoint

    最近在做cas单点登录时,由于是单点登录.必然会涉及到单点注销,然而在做单点注销时由于对cas注销机制不了解加之测试条件所致,所有测试都是在本机下完成(机器性能较低,没用虚拟机):导致折腾了很久.网上 ...

  6. scrapy爬虫成长日记之创建工程-抽取数据-保存为json格式的数据

    在安装完scrapy以后,相信大家都会跃跃欲试想定制一个自己的爬虫吧?我也不例外,下面详细记录一下定制一个scrapy工程都需要哪些步骤.如果你还没有安装好scrapy,又或者为scrapy的安装感到 ...

  7. poj1185

    状态压缩dp #include <cstdio> #include <cstring> #include <cstdlib> #include <iostre ...

  8. Codebook model 视频抠像 xp sp3 + vs2005 + OpenCV 2.3.1

    Codebook model 视频抠像 xp sp3 + vs2005 + OpenCV 2.3.1 源码及详细文档下载 svn checkout http://cvg02.googlecode.co ...

  9. codeforces C1. The Great Julya Calendar 解题报告

    题目链接:http://codeforces.com/problemset/problem/331/C1 这是第一次参加codeforces比赛(ABBYY Cup 3.0 - Finals (onl ...

  10. Extjs的数据读取器store和后台返回类型简单解析

    工作中用到了Extjs,从后台获取数据的时候,用到了extjs自己的Ext.data.store方法,然后封装了ExtGridReturn方法, 目的:前台用到Ext.data.store读取从后台传 ...