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

上下界网络流。

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

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

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

#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. Spring下读取properties文件

    由于在spring的xml文件中配置了 <bean id="validator" class="org.springframework.validation.bea ...

  2. 在SAP CRM WebClient UI中用javascript触发ABAP event

    环境:SAP CRM WebClient UI 需求:在WebClient UI里不通过用户手动点击,而是使用JavaScript代码自动触发ABAP后台的代码. 解决方案: 1. 定义一个hidde ...

  3. python打飞机pro版

    # -*- coding: utf-8 -*- import pygame from sys import exit import random pygame.init() screen = pyga ...

  4. poj2312Battle City BFS

    题意: M行N列矩阵, 'Y'表示开始位置, 'T'表示目标位置, 从开始位置到目标位置至少需要走多少步,其中, 'S', 'R'表示不能走, 'B' 花费为2, 'E'花费为1. 思路:纯 BFS. ...

  5. Error:(3, 32) java: 程序包org.springframework.boot不存在

     解决方案一: 找同事传一份D:\maven_repository\org\springframework\boot  ,如图所示的位置,添加进去立刻就不报红.我也可以给你发....  解决方案二: ...

  6. js 两个数组进行去重处理,返回去重后的数组

    1.去重的方法为: array_diff(a, b) { for (var i = 0; i < b.length; i++) { for (var j = 0; j < a.length ...

  7. shell脚本,如何监控目录下的文件内容是否被修改。

    第一种方法是通过cmp来进行比对[root@localhost bo]# ls .html .html .html .html .html .html .html .html .html cat.sh ...

  8. Linux安全调优1:CentOS防火墙的设置与优化

    CentOS防火墙的设置与优化 时间:2014-09-11 02:11来源:blog.csdn.net 作者:成长的小虫 的BLOG 举报 点击:4908次 一.设置主机防火墙. 开放: 服务器的:w ...

  9. sublime text 3143 最新激活方法

    1)输入激活码 —– BEGIN LICENSE —– TwitterInc 200 User License EA7E-890007 1D77F72E 390CDD93 4DCBA022 FAF60 ...

  10. 【dp】数字游戏&寒假祭

    区间DP 题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按 ...