//有流量上下界的网络流
//Time:47Ms Memory:1788K
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std; #define MAXC 25
#define MAXN 250
#define MAXE 100000
#define INF 0x3f3f3f3f struct Edge{
int u,v,f,next;
Edge(){}
Edge(int uu, int vv, int ff, int nn):u(uu), v(vv), f(ff), next(nn){}
}e[MAXE]; int n, m;
int S,T,s,t;
int sn[MAXN], sm[MAXC]; //行和,列和
int up[MAXN][MAXC], down[MAXN][MAXC]; //上界与下界
int in[MAXN], out[MAXN]; //出入度
int h[MAXN], le;
int d[MAXN];
int ans[MAXN][MAXC]; void add(int u,int v,int f)
{
e[le] = Edge(u, v, f, h[u]); h[u] = le++;
e[le] = Edge(v, u, 0, h[v]); h[v] = le++;
} bool Init()
{
int TT;
bool result = true;
scanf("%d", &TT);
while(TT--){
int x, y, v;
int x1,x2,y1,y2;
char op[2];
scanf("%d%d%s%d", &x, &y, op, &v);
if(!result) continue;
x1 = x2 = x; y1 = y2 = y;
if(x == 0){ x1 = 1; x2 = n;}
if(y == 0){ y1 = 1; y2 = m;}
for(int i = x1; i <= x2; i++)
{
for(int j = y1; j <= y2; j++)
{
if(op[0] == '='){
if(v > up[i][j] || v < down[i][j]) result = false;
up[i][j] = down[i][j] = v;
}
else if(op[0] == '>')
down[i][j] = max(down[i][j], v+1);
else up[i][j] = min(up[i][j], v-1);
if(up[i][j] < down[i][j]) result = false;
}
}
}
return result;
} void Build() //建图
{
memset(h, -1, sizeof(h));
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
le = 0;
s = 0; t = n+m+1; //原图源汇点
S = t+1; T = t+2; //超级源汇点
for(int i =1; i <= n; i++) //建立初始各边
{
for(int j = 1; j <= m; j++)
{
int x = i, y = j + n;
add(x, y, up[i][j] - down[i][j]);
in[y] += down[i][j]; out[x] += down[i][j];
}
}
for(int i = 1; i <= n; i++) //从s流出的流量
{
in[i] += sn[i]; out[s] += sn[i];
}
for(int i = 1; i <= m; i++) //到t的流量
{
in[t] += sm[i]; out[i+n] += sm[i];
}
for(int i = 0; i <= n+m+1; i++) //新建补边
{
int x,y,w;
if(in[i] > out[i]) {
out[S] += in[i] - out[i];
add(S,i,in[i] - out[i]);
}
else if(in[i] < out[i]) add(i, T, out[i] - in[i]);
}
add(t, s, INF);
} bool BFS()
{
memset(d, -1, sizeof(d));
queue<int> q;
q.push(S); d[S] = 0;
while(!q.empty()){
int cur = q.front();
q.pop();
for(int i = h[cur]; i != -1; i = e[i].next)
{
int v = e[i].v;
if(d[v] == -1 && e[i].f)
{
d[v] = d[cur] + 1;
if(v == T) return true;
q.push(v);
}
}
}
return false;
} int DFS(int x, int sum)
{
if (x == T || sum == 0) return sum;
int src = sum;
for (int i = h[x]; i != -1; i = e[i].next)
{
int v = e[i].v;
if (d[v] == d[x] + 1 && e[i].f)
{
int tmp = DFS(v, min(sum, e[i].f));
e[i].f -= tmp;
e[i^1].f += tmp;
sum -= tmp;
}
}
return src - sum;
} int Dinic()
{
int maxflow = 0;
while(BFS()){
maxflow += DFS(S, INF);
}
return maxflow;
} int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int TT;
scanf("%d",&TT);
while(TT--){
memset(e, 0, sizeof(e));
memset(up, INF, sizeof(up));
memset(down, 0 ,sizeof(down));
scanf("%d%d", &n,&m);
for(int i = 1; i <= n; i++)
scanf("%d", &sn[i]);
for(int i = 1; i <= m; i++)
scanf("%d", &sm[i]);
if(!Init()){ //预处理得到矛盾
printf("IMPOSSIBLE\n\n");
continue;
}
Build(); //构图
if(Dinic() != out[S]) printf("IMPOSSIBLE\n\n");
else{
for(int i = 1; i <= n; i++)
for(int j = h[i]; j != -1; j = e[j].next)
ans[i][e[j].v-n] = e[j^1].f + down[i][e[j].v-n];
for(int i = 1; i <= n; i++)
{
for(int j = 1; j < m; j++)
printf("%d ", ans[i][j]);
printf("%d\n", ans[i][m]);
}
printf("\n");
}
}
return 0;
}

ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)的更多相关文章

  1. 有源汇有上下界最小流 DInic + 各种优化 模板

    例题:loj117 : https://loj.ac/problem/117 //其实就是判断可行流后倒着求一遍最大流 #include <iostream> #include <c ...

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

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

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

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

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

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

  5. poj_2396 有上下界的网络流

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

  6. BZOJ 2406 二分+有上下界的网络流判定

    思路: 求出每行的和  sum_row 每列的和   sum_line 二分最后的答案mid S->i  流量[sum_row[i]-mid,sum_row[i]+mid] i->n+j ...

  7. BZOJ 3876 有上下界的网络流

    思路: 套用有上下界的网络流 就好了   (这算是裸题吧) 比如 有条 x->y 的边  流量上限为R 下限为L 那么du[x]-=L,du[y]+=L 流量上限变成R-L du[x]>0 ...

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

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

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

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

随机推荐

  1. json的场景应用与实战

    首先 要感谢慕课网的老师 地址:http://www.imooc.com/learn/68 下面我来开始总结: 什么是json的这些我就不多说了  不懂百度 <?php function cre ...

  2. ssh 公钥登陆的问题

    我在A,B两台机器上面使用无密码登陆的方式 在A主机上面生成公钥 复制到了B主机的authorized_keys文件里面 发现还是要输入密码 问题1 权限问题  .ssh 目录必须是 700 auth ...

  3. Unity Animator动画状态机 深入理解(二)IK控制

    IK还是一个很神奇和实用的东西啊,起码可以用代码来控制人物骨骼位置还是很爽的.因为不是动画师~ 这篇可能跟Animator没啥关系了哈,都是代码层的. 看了一官方的案例,老的,有些问题,自己修改了一下 ...

  4. 查看Mysql版本号 (最简单的是status )

    一.使用命令行模式进入mysql会看到最开始的提示符;二.命令行中使用status可以看到;三.使用系统函数等等,   查看版本信息 #1使用命令行模式进入mysql会看到最开始的提示符 Your M ...

  5. JAVA源码分析-HashMap源码分析(二)

    本文继续分析HashMap的源码.本文的重点是resize()方法和HashMap中其他的一些方法,希望各位提出宝贵的意见. 话不多说,咱们上源码. final Node<K,V>[] r ...

  6. Think twice before doing~

    1.遇到任何矛盾,对事不对人. 2.接到朋友等人的求助电话后,一定要先问清楚对方有什么事情,然后再告诉他(她)能不能帮她(他). 3.如果没有十足的把握和必要,就不要轻易说假话. 4.少提自己的私事, ...

  7. sql 注入问题

    1. 关于使用intval强制转换成数字的问题.数字大于2147483647会出现溢出出现负数.使用个方法来替代这个吧$n="\n";$a=2147483648.05555;ech ...

  8. java 多线程 4 线程池

    系统启动一个新线程的成本是比较高的,因为它涉及到与操作系统的交互.在这种情况下,使用线程池可以很好的提供性能,尤其是当程序中需要创建大量生存期很短暂的线程时,更应该考虑使用线程池. 与数据库连接池类似 ...

  9. zabbix3配置短信报警

    需求:在zabbix服务器配置短信报警,当服务出现故障达到预警级别是通过发送短信的形式告诉运维人员,以便及时处理. 一.zabbix服务器端配置短信脚本 我的短信脚本放置位置为 /etc/zabbix ...

  10. 深入理解Java中的String

    一.String类 想要了解一个类,最好的办法就是看这个类的实现源代码,来看一下String类的源码: public final class String implements java.io.Ser ...