ZOJ1994 & POJ2396:Budget——题解
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——题解的更多相关文章
- 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 ...
- POJ2396 Budget 【带下界的最大流】
Budget Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 5962 Accepted: 2266 Special ...
- POJ2396:Budget(带下界的网络流)
Budget Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 8946 Accepted: 3327 Special ...
- POJ2396 Budget
Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 7401 Accepted: 2764 Special Judge D ...
- poj2396 Budget 上下界可行流
Budget:http://poj.org/problem?id=2396 题意: 给定一个棋盘,给定每一行每一列的和,还有每个点的性质.求一个合理的棋盘数值放置方式. 思路: 比较经典的网络流模型, ...
- POJ2396 Budget(有源汇流量有上下界网络的可行流)
题目大概给一个有n×m个单元的矩阵,各单元是一个非负整数,已知其每行每列所有单元的和,还有几个约束条件描述一些单元是大于小于还是等于某个数,问矩阵可以是怎样的. 经典的流量有上下界网络流问题. 把行. ...
- poj2396 Budget(有源汇上下界可行流)
[题目链接] http://poj.org/problem?id=2396 [题意] 知道一个矩阵的行列和,且知道一些格子的限制条件,问一个可行的方案. [思路] 设行为X点,列为Y点,构图:连边(s ...
- 【POJ2396】Budget(上下界网络流)
Description We are supposed to make a budget proposal for this multi-site competition. The budget pr ...
随机推荐
- Linux 下获取通讯IP
#!/bin/sh # filename: get_net.sh default_route=$(ip route show) default_interface=$() address=$(ip a ...
- MySQL高级-查询截取分析
一.如何分析 1.观察.至少跑1天,看看生产的慢SQL情况. 2.开启慢查询日志,设置阙值比如超过5秒钟的就是慢SQL,并将它抓取出来. 3.explain + 慢SQL分析 4.show profi ...
- SpringBoot学习:获取yml和properties配置文件的内容
项目下载地址:http://download.csdn.net/detail/aqsunkai/9805821 (一)yml配置文件: pom.xml加入依赖: <!-- 支持 @Configu ...
- android分析windowManager、window、viewGroup之间关系(二)
三.接上一节,分析windowManager中添加一个悬浮框的方式,首先看代码 WindowManager.LayoutParams params = new LayoutParams(); para ...
- VIN码识别:让VIN码采集so easy!
近几年汽车后市场呈喷井式发展,在过去的半年,汽车后市场规模已高达万亿级,产业前景广阔,与此同时行业运营也受信息区域化.数据不统一的制约,让企业面临着效率低下.规模化运行困难的痛点. 在汽车配件市场中, ...
- Python学习笔记(一)一一一环境安装错误总结
第三方库安装 1 windows存在多个版本的python,pip安装Python库失败 解决方案:进入对应官网下载安装包,步骤:1 下载安装包到C:\Python36\Lib\site-pack ...
- 从零开始的Python学习Episode 2——运算符与while循环
一.算术运算符 加法:+,减法:-,乘法*,除法/,整除(地板除)//,取余%,乘方**. 二.逻辑运算符 且:and,或:or,非:not 优先级:not>and>or 短路原则: 对 ...
- POJ 1755 Triathlon(线性规划の半平面交)
Description Triathlon is an athletic contest consisting of three consecutive sections that should be ...
- 第十八次ScrumMeeting会议
第十八次Scrum Meeting 时间:2017/12/8 地点:线上+SPR咖啡馆 人员:蔡帜 王子铭 游心 解小锐 王辰昱 李金奇 杨森 陈鑫 赵晓宇 照片: 目前工作进展 名字 今日 明天的工 ...
- BluetoothAdapter解析
这篇文章将会详细解析BluetoothAdapter的详细api, 包括隐藏方法, 每个常量含义. 一 BluetoothAdapter简介 1.继承关系 该类仅继承了Object类; 2.该类作用 ...