给定矩阵的每行每列的和,和一些大于小于等于的限制。然后需要求出一组可行解。

上下界网络流。

大概的思想就是计算出每一个点他需要强行流入或者流出的量,然后建出超级源点和汇点,然后删除下界,就可以判断是否可行。

然后把新的上界作为限制,在原图中跑一边。

然后就是必须的+原图中的进行计算。

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
int up[205][205],down[205][205],tt,n,m,row[205];
#define inf 0x3f3f3f3f
#define maxn 50005
int ttt,clu[205],S=maxn-4,T=maxn-3,SS=maxn-2,TT=maxn-1;
int fr[maxn],h[maxn],to[maxn],ne[maxn],fl[maxn],en=0,ans,a[205][205];
int du[maxn],id[205][205],tot,Sum,s,t,ban[maxn],SSum,SSSum; void add(int a,int b,int c)
{
fr[en]=a;to[en]=b;ne[en]=h[a];fl[en]=c;h[a]=en++;
fr[en]=b;to[en]=a;ne[en]=h[b];fl[en]=0;h[b]=en++;
} int dis[maxn];
queue<int>q; bool tell()
{
memset(dis,-1,sizeof dis); dis[s]=0; q.push(s);
while (!q.empty())
{
int x=q.front();q.pop();
for (int i=h[x];i>=0;i=ne[i])
if (dis[to[i]]==-1&&fl[i]>0&&!ban[i])
dis[to[i]]=dis[x]+1,q.push(to[i]);
}
return dis[t]!=-1;
} int zeng(int k,int now)
{
int ret=0;
if (k==t) return now;
for (int i=h[k];i>=0&&now>ret;i=ne[i])
if (dis[to[i]]==dis[k]+1&&fl[i]&&!ban[i]){
int tmp=zeng(to[i],min(fl[i],now-ret));
fl[i]-=tmp; fl[i^1]+=tmp; ret+=tmp;
}
if (!ret) dis[k]=-1;
return ret;
} int dinic(int S,int T)
{
int ret=0,tmp=0;//printf("dinic %d %d\n",S,T);
s=S;t=T;
while (tell()) while (tmp=zeng(s,inf)) ret+=tmp;
return ret;
} void build()
{
en=0;memset(h,-1,sizeof h);memset(a,0,sizeof a);
memset(du,0,sizeof du);
memset(ban,0,sizeof ban);Sum=0;
tot=0;
F(i,1,n) F(j,1,m)
{
if (up[i][j]<down[i][j]) {ans=0;return;}
du[i]-=down[i][j];
du[j+n]+=down[i][j];
up[i][j]-=down[i][j];
a[i][j]+=down[i][j];
add(i,j+n,up[i][j]);
}
F(i,1,n) add(S,i,row[i]);
F(j,n+1,n+m) add(j,T,clu[j-n]);
add(T,S,inf);
F(i,1,n+m)
{
if (du[i]>0) add(SS,i,du[i]),Sum+=du[i];
else if (du[i]<0) add(i,TT,-du[i]);
}
if (dinic(SS,TT)!=Sum) {ans=0;return;}
else
{
ban[en-1]=1;ban[en-2]=1;
for (int i=h[SS];i>=0;i=ne[i]) ban[i]=ban[i^1]=1;
for (int i=h[TT];i>=0;i=ne[i]) ban[i]=ban[i^1]=1;
if (dinic(S,T)!=SSum) {ans=0;return;}
F(i,1,n)
{
for (int j=h[i];j>=0;j=ne[j])
a[i][to[j]-n]+=fl[j^1];
}
ans=1; return;
}
} int main()
{
scanf("%d",&tt);
while (tt--)
{
memset(down,0,sizeof down);
memset(up,0x3f,sizeof up);
scanf("%d%d",&n,&m);SSum=SSSum=0;
F(i,1,n) scanf("%d",&row[i]),SSum+=row[i];
F(i,1,m) scanf("%d",&clu[i]),SSSum+=clu[i];
scanf("%d",&ttt);
F(i,1,ttt)
{
int x,y,z;char s[11];
scanf("%d%d%s%d",&x,&y,s,&z);
switch(s[0])
{
case '>':
if (!x) F(i,1,n)
{
if (!y) F(j,1,m)
down[i][j]=max(down[i][j],z+1);
else
down[i][y]=max(down[i][y],z+1);
}
else
{
if (!y) F(j,1,m)
down[x][j]=max(down[x][j],z+1);
else
down[x][y]=max(down[x][y],z+1);
}
break;
case '=':
if (!x) F(i,1,n)
{
if (!y) F(j,1,m)
{
up[i][j]=min(up[i][j],z);
down[i][j]=max(down[i][j],z);
}
else
{
up[i][y]=min(up[i][y],z);
down[i][y]=max(down[i][y],z);
}
}
else
{
if (!y) F(j,1,m)
{
up[x][j]=min(up[x][j],z);
down[x][j]=max(down[x][j],z);
}
else
{
up[x][y]=min(up[x][y],z);
down[x][y]=max(down[x][y],z);
}
}
break;
case '<':
if (!x) F(i,1,n)
{
if (!y) F(j,1,m)
up[i][j]=min(up[i][j],z-1);
else
up[i][y]=min(up[i][y],z-1);
}
else
{
if (!y) F(j,1,m)
up[x][j]=min(up[x][j],z-1);
else
up[x][y]=min(up[x][y],z-1);
}
break;
}
}
build();
if ((!ans)||(SSum!=SSSum)) printf("IMPOSSIBLE\n");
else
{
F(i,1,n) F(j,1,m)
printf("%d%c",a[i][j],j==m?'\n':' ');
}
if (tt!=0)
printf("\n");
}
}

  

POJ 2396 Budget ——有上下界的网络流的更多相关文章

  1. POJ 2396 Budget 有上下界的网络流

    POJ 2396  Budget 题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测.矩阵规模小于200*20. 网络流的模型是显而易见的,不过对 ...

  2. poj 2396 Budget 边容量有上下界的最大流

    题意: 给一个矩阵的每行和及每列和,在给一些行列或点的限制条件.求一个满足的矩阵. 分析: 转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法. 代码: //poj 2396 / ...

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

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

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

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

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

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

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

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

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

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

  8. poj_2396 有上下界的网络流

    题目大意 一个mxn的矩阵,给出矩阵中每一行的和sh[1,2...m]以及每一列的数字的和目sv[1,2...n],以及矩阵中的一些元素的范围限制,比如a[1][2] > 1, a[2][3] ...

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

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

随机推荐

  1. 基于Python的Web应用开发实战——3 模板

    要想开发出易于维护的程序,关键在于编写形式简洁且结构良好的代码. 当目前为止,你看到的示例都太简单,无法说明这一点,但Flask视图函数的两个完全独立的作用却被融合在了一起,这就产生了一个问题. 视图 ...

  2. sql视图和表的区别

    整理一下视图和表的区别 区别: 1.视图是已经编译好了的sql,表不是 2.视图没有实际的物理存储记录,表有 3.视图是逻辑概念,表可以进行修改 5.表是内模式,视图是外模式 6.视图是我们查看表的方 ...

  3. chosen选择框加载数据

    1.单选$(select).val($("#id").val());$(select).trigger("chosen:updated"); 2.多选 func ...

  4. awk纯干货

    AWK的惊人表现: Awk设计的目的:简化一般文本处理的工作. 属于POSIX的一部分. AWK命令行: Awk的调用可以定义变量.提供程序并且指定输入文件: Awk [ -F fs ]  [ -v ...

  5. mysql中常用函数简介(不定时更新)

    常用函数version() 显示当前数据库版本database() 返回当前数据库名称user() 返回当前登录用户名inet_aton(IP) 返回IP地址的数值形式,为IP地址的数学计算做准备in ...

  6. ssh 免密码登录 与 密钥公钥原理讲解

    前言 由于最近频繁需要登录几个服务器,每次登录都需要输入密码,故相对麻烦. 由于个人服务器用于实验,故对安全性要求不是很高,故想实现ssh免密登录. 通过阅读ssh 公钥私钥认证操作及原理以及ssh公 ...

  7. RN笔记

    https://facebook.github.io/react-native/docs/using-a-listview.html react native类似于react,不过它使用的是原生组件, ...

  8. Linux中的定时任务简单操作实例

    今天,我怀着一颗感恩的心,写了一个小小的定时任务,细想还是写个简单的例子吧,希望能帮到你! 首先我在/usr/local/文件夹下创建了一个文件,hah.sh文件 在hah.sh里面编写shell脚本 ...

  9. 【php】 PHP 支持 9 种原始数据类型

    PHP 支持 9 种原始数据类型. 四种标量类型: boolean(布尔型) integer(整型) float(浮点型,也称作 double) string(字符串) 三种复合类型: array(数 ...

  10. 剑指Offer(书):反转链表

    题目:输入一个链表,反转链表后,输出新链表的表头. 分析:要分清他的前一个节点和后一个节点,开始的时候前节点为null,后节点为head.next,之后,反转. public ListNode Rev ...