poj2396 Budget 上下界可行流
Budget:http://poj.org/problem?id=2396
题意:
给定一个棋盘,给定每一行每一列的和,还有每个点的性质。求一个合理的棋盘数值放置方式。
思路:
比较经典的网络流模型,把每一列看成一个点,每一行看成一个点,利用上下界可行流的思路建图就行了,注意这里由于是严格的小于和大于,所以可以利用 x+1, x-1。
还有就是这道题的0 , 0 说的是对整张图的操作。
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <iomanip>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <stack>
#include <cmath>
#include <queue>
#include <list>
#include <map>
#include <set>
#include <cassert> /* ⊂_ヽ
\\ Λ_Λ 来了老弟
\('ㅅ')
> ⌒ヽ
/ へ\
/ / \\
レ ノ ヽ_つ
/ /
/ /|
( (ヽ
| |、\
| 丿 \ ⌒)
| | ) /
'ノ ) Lノ */ using namespace std;
#define lson (l , mid , rt << 1)
#define rson (mid + 1 , r , rt << 1 | 1)
#define debug(x) cerr << #x << " = " << x << "\n";
#define pb push_back
#define pq priority_queue typedef long long ll;
typedef unsigned long long ull;
//typedef __int128 bll;
typedef pair<ll ,ll > pll;
typedef pair<int ,int > pii;
typedef pair<int,pii> p3; //priority_queue<int> q;//这是一个大根堆q
//priority_queue<int,vector<int>,greater<int> >q;//这是一个小根堆q
#define fi first
#define se second
//#define endl '\n' #define boost ios::sync_with_stdio(false);cin.tie(0)
#define rep(a, b, c) for(int a = (b); a <= (c); ++ a)
#define max3(a,b,c) max(max(a,b), c);
#define min3(a,b,c) min(min(a,b), c); const ll oo = 1ll<<;
const ll mos = 0x7FFFFFFF; //
const ll nmos = 0x80000000; //-2147483648
const int inf = 0x3f3f3f3f;
const ll inff = 0x3f3f3f3f3f3f3f3f; //
const int mod = 1e9+;
const double esp = 1e-;
const double PI=acos(-1.0);
const double PHI=0.61803399; //黄金分割点
const double tPHI=0.38196601; template<typename T>
inline T read(T&x){
x=;int f=;char ch=getchar();
while (ch<''||ch>'') f|=(ch=='-'),ch=getchar();
while (ch>=''&&ch<='') x=x*+ch-'',ch=getchar();
return x=f?-x:x;
} inline void cmax(int &x,int y){if(x<y)x=y;}
inline void cmax(ll &x,ll y){if(x<y)x=y;}
inline void cmin(int &x,int y){if(x>y)x=y;}
inline void cmin(ll &x,ll y){if(x>y)x=y;} /*-----------------------showtime----------------------*/ const int maxn = 1e4+;
int n,m;
struct E{
int v,val,id;
int nxt;
}edge[maxn];
int head[maxn],gtot;
void addedge(int u,int v,int val, int id){
edge[gtot].v = v;
edge[gtot].val = val;
edge[gtot].nxt = head[u];
edge[gtot].id = -;
head[u] = gtot++; edge[gtot].v = u;
edge[gtot].val = ;
edge[gtot].nxt = head[v];
edge[gtot].id = id;
head[v] = gtot++;
} int dis[maxn],cur[maxn],all;
bool bfs(int s,int t) {
memset(dis, inf, sizeof(dis)); for(int i=; i<=all; i++) cur[i] = head[i];
queue<int>que; que.push(s);
dis[s] = ;
while(!que.empty()){
int u = que.front(); que.pop();
for(int i=head[u]; ~i; i=edge[i].nxt){
int v = edge[i].v,val = edge[i].val;
if(val > && dis[v] > dis[u] + ){
dis[v] = dis[u]+ ;
que.push(v);
}
}
}
return dis[t] < inf;
}
int dfs(int u,int t,int maxflow){
if(u == t || maxflow == ) return maxflow;
for(int i=cur[u]; ~i; i=edge[i].nxt){
cur[u] = i;
int v=edge[i].v,val = edge[i].val;
if(val > &&dis[v] == dis[u] + ){
int f = dfs(v, t, min(maxflow, val));
if(f > ) {
edge[i].val -= f;
edge[i ^ ].val += f;
return f;
}
}
}
return ;
}
int dinic(int s,int t){
int flow = ;
while(bfs(s, t)){
while(int f = dfs(s, t, inf)) flow += f;
}
return flow;
} int low[][],high[][],du[];
char op[];
int main(){
int T;
scanf("%d", &T);
while(T--){
memset(head, -, sizeof(head));
memset(low, , sizeof(low));
memset(high, inf, sizeof(high));
memset(du, , sizeof(du));
gtot = ;
scanf("%d%d", &n, &m);
int s = , t = n+m+, ss = n+m+, tt = n+m+;
all = tt;
int s1 = , s2 = ;
for(int i=; i<=n; i++) {
int x; scanf("%d", &x);
addedge(s, i, , -);
du[s] -= x;
du[i] += x;
s1 += x;
}
for(int i=; i<=m; i++){
int x; scanf("%d", &x);
addedge(n+i, t, , -);
du[t] += x;
du[n+i] -= x;
s2 += x;
} int c; scanf("%d", &c);
int flag = ;
while(c--){
int u,v,x;
scanf("%d %d %s %d", &u, &v, op, &x);
if(u == && v == ){
for(int i=; i<=n; i++) {
for(int j=; j<=m; j++){
if(op[] == '>') low[i][j] = max(low[i][j],x+);
else if(op[] == '<') high[i][j] = min(high[i][j], x-);
else if(op[] == '=')
{
low[i][j] = max(low[i][j], x), high[i][j] = min(high[i][j], x);
if(low[i][j] != x || high[i][j] != x) flag = ;
}
}
}
}
else if(u == ) {
for(int i=; i<=n; i++) {
if(op[] == '>') low[i][v] = max(low[i][v],x+);
else if(op[] == '<') high[i][v] = min(high[i][v], x-);
else if(op[] == '=')
{
low[i][v] = max(low[i][v], x), high[i][v] = min(high[i][v], x);
if(low[i][v] != x || high[i][v] != x) flag = ;
}
}
}
else if(v == ){
for(int i=; i<=m; i++) {
if(op[] == '>') low[u][i] = max(low[u][i],x+);
else if(op[] == '<') high[u][i] = min(high[u][i], x-);
else {
low[u][i] = max(low[u][i], x), high[u][i] = min(high[u][i], x);
if(low[u][i] != x || high[u][i] != x) flag = ;
}
}
}
else {
if(op[] == '>') low[u][v] = max(low[u][v],x+);
else if(op[] == '<') high[u][v] = min(high[u][v], x-);
else {
low[u][v] = max(low[u][v], x), high[u][v] = min(high[u][v], x);
if(low[u][v] != x || high[u][v] != x) flag = ;
}
}
} for(int i=; i<=n; i++) {
for(int j=; j<=m; j++){
du[i] -= low[i][j];
du[j+n] += low[i][j];
addedge(i, n + j, high[i][j] - low[i][j], );
if(high[i][j] < low[i][j]) flag = ;
}
} int sum = ;
for(int i=s; i<=t; i++) {
if(du[i] > ) addedge(ss, i, du[i], -), sum += du[i];
if(du[i] < )addedge(i, tt, -du[i], -);
}
if(s1 != s2 || !flag) {
puts("IMPOSSIBLE");
if(T) puts("");
continue;
}
int f = dinic(ss, tt); if(f + s1==sum) {
for(int i=n+;i<=n+m; i++){
for(int j=head[i]; ~j; j=edge[j].nxt){
int v = edge[j].v,val = edge[j].val;
low[v][i-n] += val;
}
}
for(int i=; i<=n; i++){
for(int j=; j<=m; j++){
if(j < m)printf("%d ", low[i][j]);
else printf("%d\n", low[i][j]);
}
}
}
else puts("IMPOSSIBLE");
if(T) puts("");
}
return ;
}
/*
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
*/
poj2396 Budget 上下界可行流的更多相关文章
- [poj2396]Buget[上下界可行流]
题意:有一个n*m的方阵,里面的数字未知,但是我们知道如下约束条件:每一行的数字的和每一列的数字的和某些格子有特殊的大小约束,用大于号,小于号和等于号表示问:是否存在用正数填充这个方阵的方案,满足所有 ...
- POJ2396 Budget [有源汇上下界可行流]
POJ2396 Budget 题意:n*m的非负整数矩阵,给出每行每列的和,以及一些约束关系x,y,>=<,val,表示格子(x,y)的值与val的关系,0代表整行/列都有这个关系,求判断 ...
- poj2396 Budget(有源汇上下界可行流)
[题目链接] http://poj.org/problem?id=2396 [题意] 知道一个矩阵的行列和,且知道一些格子的限制条件,问一个可行的方案. [思路] 设行为X点,列为Y点,构图:连边(s ...
- 有源汇上下界可行流(POJ2396)
题意:给出一个n*m的矩阵的每行和及每列和,还有一些格子的限制,求一组合法方案. 源点向行,汇点向列,连一条上下界均为和的边. 对于某格的限制,从它所在行向所在列连其上下界的边. 求有源汇上下界可行流 ...
- [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流
poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...
- poj2396有源汇上下界可行流
题意:给一些约束条件,要求算能否有可行流,ps:刚开始输入的是每一列和,那么就建一条上下界相同的边,这样满流的时候就一定能保证流量相同了,还有0是该列(行)对另一行每个点都要满足约束条件 解法:先按无 ...
- ZOJ_2314_Reactor Cooling_有上下界可行流模板
ZOJ_2314_Reactor Cooling_有上下界可行流模板 The terrorist group leaded by a well known international terroris ...
- ZOJ1994有源汇上下界可行流
http://fastvj.rainng.com/contest/236779#problem/G Description: n 行 m 列 给你行和 与 列和 然后有Q个限制,表示特定单元格元素大小 ...
- LOJ [#115. 无源汇有上下界可行流](https://loj.ac/problem/115)
#115. 无源汇有上下界可行流 先扔个板子,上下界的东西一点点搞,写在奇怪的合集里面 Code: #include <cstdio> #include <cstring> # ...
随机推荐
- java多线程核心api以及相关概念(一)
这篇博客总结了对线程核心api以及相关概念的学习,黑体字可以理解为重点,其他的都是我对它的理解 个人认为这些是学习java多线程的基础,不理解熟悉这些,后面的也不可能学好滴 目录 1.什么是线程以及优 ...
- OLE--SWT高级控件
OLE和ActiveX控件的支持 OLE(Object Link Embeded)是指在程序之间链接和嵌入对象数据.通过OLE技术可以在一个应用程序中执行其他的应用程序. 而ActiveX ...
- sift、surf、orb 特征提取及最优特征点匹配
目录 sift sift特征简介 sift特征提取步骤 surf surf特征简介 surf特征提取步骤 orb orb特征简介 orb特征提取算法 代码实现 特征提取 特征匹配 附录 sift si ...
- Mac 10.14.4 编译openjdk1.9源码 及集成clion动态调试
警告⚠️:本文耗时很长,先做好心理准备:编译openjdk源码需要很大的耐心,因为要踩很多坑,解决很多问题,本人从编译开始到结束用了两天时间,按照本篇教程踩坑会少许:谢谢观看 一.获取openjdk源 ...
- 封装 Gson 解析Json到对象是否失败
在使用Google的 Gson 类库解析 Json 数据时,难免会出现解析失败的情况. 在这种情况下,使用 if(obj == null) 是不可行的,fromJson 方法会自动生成对象的实例,所以 ...
- Unity通过NTP获取网络时间
最初通过qq时间服务器获得时间,经常出现有网络也获取失败的情况. 后面寻找解决办法,查找资料终于发现通过ntp时间服务器获取网络时间的方法. 首先游戏开始获得初始化网络时间,通常只获取一次,其他时 ...
- JVM系列(3)- Java VisualVM使用
前言 Java VisualVM是jdk自带一款工具,可以十分友好的监控java进程相关的应用服务及中间件. 工具位置 jdk的bin目录下,找到jvisualvm.exe,双击打开即可. 功能介绍 ...
- 有趣的RPC理解
RPC(Remote Procedure Call)—远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议.RPC协议假定某些传输协议的存在,如TCP或UDP,为通 ...
- JAVA基础知识(三):input.nextLine() 和input.next()
next()方法在读取内容时,会过滤掉有效字符前面的无效字符,对输入有效字符之前遇到的空格键.Tab键或Enter键等结束符,next()方法会自动将其过滤掉:只有在读取到有效字符之后,next()方 ...
- Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端
多线程的操作在程序中也是比较常见的,比如开启一个线程执行一些比较耗时的操作(IO操作),而主线程继续执行当前操作,不会造成主线程阻塞.线程又分为前台线程和后台线程,区别是:整个程序必须要运行完前台线程 ...