http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1994

http://poj.org/problem?id=2396

题目大意:给一个m行n列的空矩阵,让你往上面填数(数为非负整数),使得这个矩阵满足:

1.每行/列和等于给定的每行/列和

2.一些限制条件。

限制条件限制了x,y,ch,v,使得x行y列的点的数满足(>or=or<,由ch决定)v。

特别的,如果x=0则代表y列全满足该条件,如果y=0则代表x行全满足该条件,如果全为0则代表全矩阵全满足该条件。

——————————————————————————

有二分图+上下界网络流想法,不难想到先建源汇点,源点到所有的行连一条上下界均为行和的边,所有的列到汇点连一条上下界均为列和的边。

然后整理限制条件,行和列之间连满足所有限制条件的边。

在那之后就是上下界网络流的活了。

注意:

1.可以先判断行和之和如果不等于列和之和的话就是IMPOSSIBLE。

2.限制条件如果不满足的话||第一条发生的话,记得把剩余的限制条件读完再输出。

3.我们其实可以简化,我们其实根本不需要源汇点,于是它其实可以转换成无源汇上下界网络流可行流。

原因:最开始建源汇点的时候我们发现它只连了上下界相同的边,相当于没连,以致到后来跑可行流的时候它根本不会做出任何贡献,所以大可以删掉。

4.IMPOSSIBLE不要打错……

5.ZOJ选手注意,不能填负数,最后一行不能有两个回车。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=;
const int M=;
const int INF=1e9;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int nxt,to,w;
}edge[M];
int head[N],du[N],up[][],low[][];
int cnt=-,S,T;
bool die[][];
inline void add(int u,int v,int w){
cnt++;
edge[cnt].to=v;
edge[cnt].w=w;
edge[cnt].nxt=head[u];
head[u]=cnt;
return;
}
int lev[N],cur[N],dui[N];
bool bfs(int k){
int r=;
for(int i=;i<=k;i++){
lev[i]=-;
cur[i]=head[i];
}
dui[]=S,lev[S]=;
int u,v;
for(int l=;l<=r;l++){
u=dui[l];
for(int e=head[u];e!=-;e=edge[e].nxt){
v=edge[e].to;
if(edge[e].w>&&lev[v]==-){
lev[v]=lev[u]+;
r++;
dui[r]=v;
if(v==T)return ;
}
}
}
return ;
}
int dinic(int u,int flow,int k){
if(u==k)return flow;
int res=,delta;
for(int &e=cur[u];e!=-;e=edge[e].nxt){
int v=edge[e].to;
if(edge[e].w>&&lev[u]<lev[v]){
delta=dinic(v,min(edge[e].w,flow-res),k);
if(delta>){
edge[e].w-=delta;
edge[e^].w+=delta;
res+=delta;
if(res==flow)break;
}
}
}
if(res!=flow)lev[u]=-;
return res;
}
inline void init(int m,int n){
memset(head,-,sizeof(head));
memset(du,,sizeof(du));
memset(die,,sizeof(die));
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
up[i][j]=INF;
low[i][j]=;
}
}
cnt=-;
return;
}
inline char getc(){
char ch=' ';
while(ch==' ')ch=getchar();
return ch;
}
int main(){
int t=read(),num=;
while(t--){
num++;
if(num>)puts("");
int m=read(),n=read();
init(m,n);
int tot=;
for(int i=;i<=m;i++){
int h=read();
du[i]+=h;
tot+=h;
}
for(int i=;i<=n;i++){
int l=read();
du[i+m]-=l;
tot-=l;
}
int c=read();
bool flag=;
for(int i=;i<=c;i++){
int r=read(),q=read(),a,b;
char ch=getc();
int v=read();
if(ch=='<'){a=;b=--v;}
else if(ch=='>'){a=++v;b=INF;}
else a=b=v;
if(!r&&!q){
for(int j=;j<=m&&flag;j++){
for(int k=;k<=n&&flag;k++){
if(die[j][k]&&(low[j][k]>b||low[j][k]<a)){
flag=;
break;
}
if(ch=='='){up[j][k]=low[j][k]=v;die[j][k]=;}
else if(ch=='>')low[j][k]=max(low[j][k],v);
else up[j][k]=min(up[j][k],v);
if(low[j][k]>up[j][k])flag=;
}
}
}else if(!r){
for(int j=;j<=m&&flag;j++){
if(die[j][q]&&(low[j][q]>b||low[j][q]<a)){
flag=;
break;
}
if(ch=='='){up[j][q]=low[j][q]=v;die[j][q]=;}
else if(ch=='>')low[j][q]=max(low[j][q],v);
else up[j][q]=min(up[j][q],v);
if(low[j][q]>up[j][q])flag=;
}
}else if(!q){
for(int k=;k<=n&&flag;k++){
if(die[r][k]&&(low[r][k]>b||low[r][k]<a)){
flag=;
break;
}
if(ch=='='){up[r][k]=low[r][k]=v;die[r][k]=;}
else if(ch=='>')low[r][k]=max(low[r][k],v);
else up[r][k]=min(up[r][k],v);
if(low[r][k]>up[r][k])flag=;
}
}else{
if(die[r][q]&&(low[r][q]>b||low[r][q]<a)){
flag=;
}
if(ch=='='){up[r][q]=low[r][q]=v;die[r][q]=;}
else if(ch=='>')low[r][q]=max(low[r][q],v);
else up[r][q]=min(up[r][q],v);
if(low[r][q]>up[r][q])flag=;
}
}
if(!flag||tot!=){
puts("IMPOSSIBLE");
continue;
}
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
add(i,j+m,up[i][j]-low[i][j]);
add(j+m,i,);
du[i]-=low[i][j];
du[j+m]+=low[i][j];
}
}
S=m+n+;T=S+;
int ans=,full=;
for(int i=;i<=m+n;i++){
if(du[i]>){
add(S,i,du[i]);
add(i,S,);
full+=du[i];
}else if(du[i]<){
add(i,T,-du[i]);
add(T,i,);
}
}
while(bfs(T))ans+=dinic(S,INF,T);
if(ans!=full)puts("IMPOSSIBLE");
else{
for(int i=;i<=m;i++){
for(int j=;j<=n;j++){
int id=((i-)*n+j)*-;
printf("%d",low[i][j]+edge[id].w);
if(j!=n)putchar(' ');
}
puts("");
}
}
}
return ;
}

ZOJ1994 & POJ2396:Budget——题解的更多相关文章

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

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

  2. poj2396 Budget&&ZOJ1994 Budget[有源汇上下界可行流]

    Budget Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge We are supposed to make ...

  3. POJ2396 Budget 【带下界的最大流】

    Budget Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5962   Accepted: 2266   Special ...

  4. POJ2396:Budget(带下界的网络流)

    Budget Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 8946   Accepted: 3327   Special ...

  5. POJ2396 Budget

    Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 7401   Accepted: 2764   Special Judge D ...

  6. poj2396 Budget 上下界可行流

    Budget:http://poj.org/problem?id=2396 题意: 给定一个棋盘,给定每一行每一列的和,还有每个点的性质.求一个合理的棋盘数值放置方式. 思路: 比较经典的网络流模型, ...

  7. POJ2396 Budget(有源汇流量有上下界网络的可行流)

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

  8. poj2396 Budget(有源汇上下界可行流)

    [题目链接] http://poj.org/problem?id=2396 [题意] 知道一个矩阵的行列和,且知道一些格子的限制条件,问一个可行的方案. [思路] 设行为X点,列为Y点,构图:连边(s ...

  9. 【POJ2396】Budget(上下界网络流)

    Description We are supposed to make a budget proposal for this multi-site competition. The budget pr ...

随机推荐

  1. hdu1058Humble Numbers(动态规划)

    Humble Numbers Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)To ...

  2. hdu1069Monkey and Banana(动态规划)

    Monkey and Banana Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  3. 180601-MySql性能监控工具MyTop

    文章链接:https://blog.hhui.top/hexblog/2018/06/01/180601-MySql性能监控工具MyTop/ mysql 性能监控小工具之 mytop 参考: How ...

  4. 使用InstallShield-Limited-Edition制作安装包

    1.打开此网站,进行注册,获取序列码以及下载InstallShield-Limited-Edition 2.安装完成之后,打开VisualStudio,新建项目 3.填写基本应用信息 4.配置相关信息 ...

  5. 使用flask_limiter设定API配额

    前言 闲来无事,突然想到了以前做过的关于后台API安全方面的事,关于接口访问配额的设置,flask有没有很好的库支持呢?一找还真有!主要是对照了库的官方文档自己写了下dome,以供参考. # -*- ...

  6. leetcode-零钱兑换—int溢出

     零钱兑换 给定不同面额的硬币 coins 和一个总金额 amount.编写一个函数来计算可以凑成总金额所需的最少的硬币个数.如果没有任何一种硬币组合能组成总金额,返回 -1. 示例 1: 输入: c ...

  7. 使用Python客户端(redis-py)连接Redis--华为云DCS for Redis使用经验

    使用Python连接Redis,需要先安装Python以及redis-py,以CentOS为例,介绍redis-py的客户端环境搭建. 第0步:准备工作 华为云上购买1台弹性云服务器ECS(我选了Ce ...

  8. cygwin—excellent work!

    使用cygwin的好处在于可以避免直接使用linux同时又能最大限度的节省资源,共享windows的资源. 安装cygwin 安装安简单,当然,你首先需要使用163或者国内或者亚洲比较好的镜像作为下载 ...

  9. tensorflow模型持久化保存和加载--深度学习-神经网络

    模型文件的保存 tensorflow将模型保持到本地会生成4个文件: meta文件:保存了网络的图结构,包含变量.op.集合等信息 ckpt文件: 二进制文件,保存了网络中所有权重.偏置等变量数值,分 ...

  10. pandas协助工具

    pandas有时候操作很不方便,也有可能是我不熟练吧,反正就是各种别扭.下面是我写的一个简单的json数据操作工具,能够完成简单的数据分析工作,后续会不断完善的 # coding=utf-8 impo ...