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 ...
随机推荐
- Ubuntu主题美化篇
主题美化篇 Ubuntu自带的主题简直不敢恭维,这里博主将它美化了一番,心情瞬间都好了一大截,码代码也会飞起!!先放一张我美化后的效果. 桌面和终端效果如下: unity-tweak-tool 调整 ...
- 消费者用nginx做负载均衡,提供者用zookeeper自带功能实现负载均衡
公司的项目基于阿里的Dubbo微服务框架开发.为了符合相关监管部门的安全要求,公司购买了华东1.华东2两套异地服务器,一套是业务服务器,一套是灾备服务器.准备在这两套服务器上实现Dubbo的分布式服务 ...
- 解析Java中final关键字的各种用法
首先,我们可以从字面上理解一下final这个英文单词的中文含义:“最后的,最终的; 决定性的; 不可更改的:”.显然,final关键词如果用中文来解释,“不可更改的”更为合适.当你在编写程序,可能会遇 ...
- Java学习笔记-11.运行期间类型鉴定
1.Class对象的getClasses()方法获取的是该类中所有的公共的内部类,以及从父类,父接口继承来的内部类.getinterfaces()方法返回类继承的所有接口. import javax. ...
- ubuntu server guide 学习笔记
1. 软件包 1.1. dpkg dpkg -l dpkg -l | grep apache2 dpkg -L ufw dpkg -S /etc/host.conf dpkg -i zip_3.0-4 ...
- 使用 Gradle 配置java项目
注意点 除非调试,不要print ,否则任务不会按照依赖的顺序执行,因为我们自己喜欢调试用print,但是会打乱执行顺序. 排除测试文件: sourceSets.main.java { srcDir ...
- 脚本 script 常用脚本
目录 remove_all_pyc find_all_links rename_with_slice load_json_without_dupes execution_time benchmark_ ...
- JavaScript闭包总结
闭包是你家庭中的第三者你在享受着第三者给你带来的便利时,而你的家庭也随时触发前所未有的危机(直男癌患者的观点);闭包是指有权访问另一个函数作用域中的变量的函数,创建闭包的常见的方式,就是在一个函数内部 ...
- UBUNTU如何安装tar.gz版的flash
adobe flash player的官方下载页面为:https://get.adobe.com/cn/flashplayer/ 不过近期通过APT方式以及ubuntu的软件中心都安装不了flashp ...
- Java中的线程的优先级
Java 中线程优先级简介: 1. Java 提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程. 按照线程的优先级决定应该调度哪个线程来执行. 2. 线程的优先级用数字表示, 范围从 1 到 ...