Budget

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

题目链接http://poj.org/problem?id=2396

Description:

We are supposed to make a budget proposal for this multi-site competition. The budget proposal is a matrix where the rows represent different kinds of expenses and the columns represent different sites. We had a meeting about this, some time ago where we discussed the sums over different kinds of expenses and sums over different sites. There was also some talk about special constraints: someone mentioned that Computer Center would need at least 2000K Rials for food and someone from Sharif Authorities argued they wouldn't use more than 30000K Rials for T-shirts. Anyway, we are sure there was more; we will go and try to find some notes from that meeting.

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:

The 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:

For 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的矩阵,以及每行每列的和。然后给出k个限制条件,格式为x y c w。

如果x,y代表横纵坐标,如果x=0则代表所有的横坐标,y=0则代表所有的纵坐标,c表示容量限制,可能大于、小于或等于,w就是具体的数值。

最后要你输出一种满足题中条件的情况,如果不满足则输出"IMPOSSIBLE"。

题解:

这题可以用带上下界有缘有汇网络流的标准解法就可以做,直接百度一下就好啦。

但我似乎是另外一种方式,就在这里大致说说我的思路吧。

对于"=",那么之后我们不连这里的横纵坐标,直接给答案数组赋值并且横和纵和减去相应的数。对于大于和小于,我们更新数组就行了。

最后建边的时候,边的容量为最大值减去最小值,对于一条边连接的两个点(x,y分别表示横和列),如果这条边有最小值,x,y都减去这个最小值即可。

然后跑个最大流就行了,输出路径的时候答案应该加上之前减去的最小值。

我这个思路正确性应该没问题,但代码实现出来有点复杂,我调了半天,说下注意的几个问题吧:

1.输入数据可能有矛盾,注意判断;
2.输入数据可能有重复,我在输入"="的时候对数组进行了修改,一开始没注意这点,就多减了....
3.将>x看成>=x+1好处理一些,"<"也类似;
4.由于二分图右侧的点编号为n+x,所以注意下数组的索引...

总之细心点就好了~

给出我复杂的代码...

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
#define s 0
#define t 300
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = ,M = ,MAXN = ;
int T;
int n,m,tot;
int mx[N][M],mn[N][M],head[MAXN],r[N],c[M],ans[N][M],d[MAXN];
struct Edge{
int v,next,c;
}e[(MAXN*MAXN)<<];
void adde(int u,int v,int c){
e[tot].v=v;e[tot].next=head[u];e[tot].c=c;head[u]=tot++;
e[tot].v=u;e[tot].next=head[v];e[tot].c=;head[v]=tot++;
}
bool bfs(int S,int T){
memset(d,,sizeof(d));d[S]=;
queue <int > q;q.push(S);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(!d[v] && e[i].c>){
d[v]=d[u]+;
q.push(v);
}
}
}
return d[T]!=;
}
int dfs(int S,int a){
int flow=,f;
if(S==t || a==) return a;
for(int i=head[S];i!=-;i=e[i].next){
int v=e[i].v;
if(d[v]!=d[S]+) continue ;
f=dfs(v,min(a,e[i].c));
if(f){
e[i].c-=f;
e[i^].c+=f;
flow+=f;
a-=f;
if(a==) break;
}
}
if(!flow) d[S]=-;
return flow;
}
int Dinic(){
int max_flow=;
while(bfs(,t)) max_flow+=dfs(,INF);
return max_flow;
}
int main(){
//freopen("2.txt","w",stdout);
cin>>T;
while(T--){
int ok=;
scanf("%d%d",&n,&m);
memset(mn,,sizeof(mn));
memset(mx,INF,sizeof(mx));
memset(ans,,sizeof(ans));
for(int i=;i<=n;i++) scanf("%d",&r[i]);
for(int i=;i<=m;i++) scanf("%d",&c[i]);
int tt;
scanf("%d",&tt);
while(tt--){
int u,v,w;char C;
scanf("%d %d %c %d",&u,&v,&C,&w);
if(C=='='){
if(u== && v){
for(int i=;i<=n;i++){
if(ans[i][v]){
if(ans[i][v]!=w) ok=;
continue ;
}
ans[i][v]=w;
r[i]-=w;
c[v]-=w;
}
}else if(v== && u){
for(int i=;i<=m;i++){
if(ans[u][i]){
if(ans[u][i]!=w) ok=;
continue ;
}
ans[u][i]=w;
c[i]-=w;
r[u]-=w;
}
}else if(!v && !u){
int tmp = ;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(ans[i][j]){
if(ans[i][j]!=w) ok=;
continue ;
}
ans[i][j]=w;
r[i]-=w;c[j]-=w;
}
}
}else{
if(ans[u][v]){
if(ans[u][v]!=w) ok=;
continue ;
}
r[u]-=w;c[v]-=w;
ans[u][v]=w;
}
}else if(C=='>'){
if(u== && v){
for(int i=;i<=n;i++) mn[i][v]=max(mn[i][v],w+);
}else if(v== && u){
for(int i=;i<=m;i++) mn[u][i]=max(mn[u][i],w+);
}else if(!v && !u){
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
mn[i][j]=max(mn[i][j],w+);
}else mn[u][v]=max(mn[u][v],w+);
}else{
if(u== && v){
for(int i=;i<=n;i++) mx[i][v]=min(mx[i][v],w-);
}else if(v== && u){
for(int i=;i<=m;i++) mx[u][i]=min(mx[u][i],w-);
}else if(!v && !u){
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
mx[i][j]=min(mx[i][j],w-);
}else mx[u][v]=min(mx[u][v],w-);
}
}
memset(head,-,sizeof(head));tot=;
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
if(mx[i][j]<mn[i][j])ok=;
if(ans[i][j]){
if(ans[i][j]<mn[i][j]||ans[i][j]>mx[i][j]) ok=;
continue ;
}
r[i]-=mn[i][j];
c[j]-=mn[i][j];
adde(i,j+n,mx[i][j]-mn[i][j]);
if(r[i]< || c[j]<) ok=;
}
}
int sum1=,sum2=;
for(int i=;i<=n;i++) sum1+=r[i];
for(int i=;i<=m;i++) sum2+=c[i];
if(sum1!=sum2) ok=;
if(!ok){
puts("IMPOSSIBLE");
continue ;
}
for(int i=;i<=n;i++) adde(s,i,r[i]);
for(int i=;i<=m;i++) adde(n+i,t,c[i]);
int max_flow=Dinic();
for(int i=head[s];i!=-;i=e[i].next){
if(e[i].c!=) ok=;
}
if(!ok) puts("IMPOSSIBLE");
else{
for(int u=;u<=n;u++){
for(int j=head[u];j!=-;j=e[j].next){
if(e[j].v<=n) continue ;
int v=e[j].v-n;
if(ans[u][v]) continue ;
ans[u][v]=ans[u][v]+mx[u][v]-e[j].c;
}
}
for(int i=;i<=n;i++){
for(int j=;j<=m;j++){
cout<<ans[i][j]<<" ";
}
cout<<endl;
}
cout<<endl;
}
}
return ;
}

POJ2396:Budget(带下界的网络流)的更多相关文章

  1. poj2396 Budget 上下界可行流

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

  2. BZOJ 3876: [Ahoi2014]支线剧情 带下界的费用流

    3876: [Ahoi2014]支线剧情 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3876 Description [故事背景] 宅 ...

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

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

  4. ZOJ 2314 Reactor Cooling 带上下界的网络流

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题意: 给n个点,及m根pipe,每根pipe用来流躺液体的, ...

  5. ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)

    //有流量上下界的网络流 //Time:47Ms Memory:1788K #include<iostream> #include<cstring> #include<c ...

  6. 【BZOJ2502】清理雪道 有上下界的网络流 最小流

    [BZOJ2502]清理雪道 Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降 ...

  7. SGU 194. Reactor Cooling(无源汇有上下界的网络流)

    时间限制:0.5s 空间限制:6M 题意: 显然就是求一个无源汇有上下界的网络流的可行流的问题 Solution: 没什么好说的,直接判定可行流,输出就好了 code /* 无汇源有上下界的网络流 * ...

  8. 【ZOJ2314】Reactor Cooling(有上下界的网络流)

    前言 话说有上下界的网络流好像全机房就我一个人会手动滑稽,当然这是不可能的 Solution 其实这道题目就是一道板子题,主要讲解一下怎么做无源无汇的上下界最大流: 算法步骤 1.将每条边转换成0~u ...

  9. ZOJ 2314 有上下界的网络流

    problemCode=2314">点击打开链接 题意:给定m条边和n个节点.每条边最少的流量和最多的流量.保证每一个节点的出入流量和相等,问能够形成吗,能够则输出每条边的流量 思路: ...

随机推荐

  1. Python学习:2.Python集成学习环境(IDE)Pycharm的安装配置以及激活方

    一.下载Pycharm Pycharm作为Python现在最流行的集成开发环境,我们今后的Python的学习也就使用Pycharm进行,那今天我们就讲一下Pycharm的安装配置以及激活 1.我们首先 ...

  2. 为什么我要放弃javaScript数据结构与算法(第二章)—— 数组

    第二章 数组 几乎所有的编程语言都原生支持数组类型,因为数组是最简单的内存数据结构.JavaScript里也有数组类型,虽然它的第一个版本并没有支持数组.本章将深入学习数组数据结构和它的能力. 为什么 ...

  3. SGU 101 Domino 题解

    鉴于SGU题目难度较大,AC后便给出算法并发布博文,代码则写得较满意后再补上.——icedream61 题目简述:暂略 AC人数:3609(2015年7月20日) 算法: 这题就是一笔画,最多只有7个 ...

  4. springmvc基础篇—使用注解方式为前台提供数据

    一.新建一个Controller package cn.cfs.springmvc.service; import java.util.ArrayList; import java.util.Hash ...

  5. win10 java环境变量配置

    首先,你应该已经安装了 Java 的 JDK 了(如果没有安装JDK,请跳转到此网址:http://www.oracle.com/technetwork/java/javase/downloads/i ...

  6. Kotlin怎样使用Android的Dagger2

    作者:Antonio Leiva 时间:Apr 11, 2017 原文链接:https://antonioleiva.com/dagger-android-kotlin/ 在Android上,创建去耦 ...

  7. fiddler之弱网测试

    今天就说一下如何使用fiddler做弱网测试 1.首先要把手机的代理打开,这就不多讲了哈,不懂得话请点传送门:https://www.cnblogs.com/fuxinxin/p/9146693.ht ...

  8. 机器视觉必知-GenICam相机通用接口标准

    机器视觉必知-GenICam相机通用接口标准 GenICam(相机通用接口): 一种通用软件接口 通用相机接口标准 目前机器视觉行业所使用的相机几乎均以相同方式来进行配置,即:---通过在注册表中的读 ...

  9. kaldi学习 - 一脚本流学习工具使用

    目录 yesno训练 先给出整体脚本如下: 分块详解 建立解码脚本 kaldi中脚本东西比较多,一层嵌一层,不易阅读. 本文以yesno为例,直接使用kaldi编译的工具,书写简易训练步骤,方便学习k ...

  10. DM8168通过GPMC接口与FPGA高速数据通信实现

    硬件:TI达芬奇TMS320DM8168(以下简称DSP).EP4CE6E22C8N(以下简称FPGA) 软件:linux-2.6.37 转载请注明出处- http://www.cnblogs.com ...