【题目链接】

http://poj.org/problem?id=2396

【题意】

知道一个矩阵的行列和,且知道一些格子的限制条件,问一个可行的方案。

【思路】

设行为X点,列为Y点,构图:连边(s,Xi,sumXi,sumXi)(Yi,t,sumYi,sumYi)(Xi,Yj,down[i][j],up[i][j])。

则问题就是求一个有源汇点st的上下界可行流。

类似于 无源无汇上下界可行流 ,添加附加源汇点ST,边权转化为up-down,由ST向每个点连边保持流量平衡。然后添加(t,s,inf),使得t的流出量与s的流入量保持相等,即等价于s为源点而t为汇点。

最后由S->T跑最大流。

【代码】

 #include<set>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define trav(u,i) for(int i=front[u];i;i=e[i].nxt)
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long ll;
const int N = 4e2+;
const int M = N*N+;
const int inf = 1e9; ll read() {
char c=getchar();
ll f=,x=;
while(!isdigit(c)) {
if(c=='-') f=-; c=getchar();
}
while(isdigit(c))
x=x*+c-'',c=getchar();
return x*f;
} struct Edge {
int u,v,cap,flow;
Edge(int u=,int v=,int cap=,int flow=)
:u(u),v(v),cap(cap),flow(flow){}
};
struct Dinic {
int n,m,s,t;
int d[N],cur[N],vis[N];
vector<int> g[N];
vector<Edge> es;
queue<int> q;
void init(int n) {
this->n=n;
es.clear();
FOR(i,,n) g[i].clear();
}
void clear() {
FOR(i,,(int)es.size()-) es[i].flow=;
}
void AddEdge(int u,int v,int w) {
es.push_back(Edge(u,v,w,));
es.push_back(Edge(v,u,,));
m=es.size();
g[u].push_back(m-);
g[v].push_back(m-);
}
int bfs() {
memset(vis,,sizeof(vis));
q.push(s); d[s]=; vis[s]=;
while(!q.empty()) {
int u=q.front(); q.pop();
FOR(i,,(int)g[u].size()-) {
Edge& e=es[g[u][i]];
int v=e.v;
if(!vis[v]&&e.cap>e.flow) {
vis[v]=;
d[v]=d[u]+;
q.push(v);
}
}
}
return vis[t];
}
int dfs(int u,int a) {
if(u==t||!a) return a;
int flow=,f;
for(int& i=cur[u];i<g[u].size();i++) {
Edge& e=es[g[u][i]];
int v=e.v;
if(d[v]==d[u]+&&(f=dfs(v,min(a,e.cap-e.flow)))>) {
e.flow+=f;
es[g[u][i]^].flow-=f;
flow+=f; a-=f;
if(!a) break;
}
}
return flow;
}
int MaxFlow(int s,int t) {
this->s=s,this->t=t;
int flow=;
while(bfs()) {
memset(cur,,sizeof(cur));
flow+=dfs(s,inf);
}
return flow;
}
} dc; int n,m,flag;
int in[N],up[N][N],down[N][N]; void can(int x,int y,int v) {
if(v<down[x][y]||v>up[x][y]) flag=;
} int main()
{
int kase=read();
while(kase--)
{
memset(in,,sizeof(in));
n=read(),m=read();
flag=;
int x,s=n+m+,t=s+,S=t+,T=S+;
dc.init(n+m+);
FOR(i,,n) {
x=read(); in[s]-=x,in[i]+=x;
dc.AddEdge(s,i,);
}
FOR(i,,m) {
x=read(); in[n+i]-=x,in[t]+=x;
dc.AddEdge(i+n,t,);
}
int K=read();
FOR(i,,n+m+) FOR(j,,n+m+)
up[i][j]=,down[i][j]=-;
while(K--) {
char s[];
int x=read(),y=read(),z;
scanf("%s",s); z=read();
if(x== && y) {
FOR(i,,n) {
if(s[]=='=') can(i,y+n,z),up[i][y+n]=down[i][y+n]=z;
if(s[]=='<') up[i][y+n]=min(up[i][y+n],z-);
if(s[]=='>') down[i][y+n]=max(down[i][y+n],z+);
}
} else
if(x && y==) {
FOR(i,,m) {
if(s[]=='=') can(x,i+n,z),up[x][i+n]=down[x][i+n]=z;
if(s[]=='<') up[x][i+n]=min(up[x][i+n],z-);
if(s[]=='>') down[x][i+n]=max(down[x][i+n],z+);
}
} else
if(x== && y==) {
FOR(i,,n) FOR(j,,m) {
if(s[]=='=') can(i,j+n,z),up[i][j+n]=down[i][j+n]=z;
if(s[]=='<') up[i][j+n]=min(up[i][j+n],z-);
if(s[]=='>') down[i][j+n]=max(down[i][j+n],z+);
}
} else {
if(s[]=='=') can(x,y+n,z),up[x][y+n]=down[x][y+n]=z;
if(s[]=='<') up[x][y+n]=min(up[x][y+n],z-);
if(s[]=='>') down[x][y+n]=max(down[x][y+n],z+);
}
}
int cur=dc.es.size();
FOR(i,,n) FOR(j,,m) {
if(up[i][j+n]<down[i][j+n]) flag=;
dc.AddEdge(i,j+n,up[i][j+n]-down[i][j+n]);
in[i]-=down[i][j+n];
in[j+n]+=down[i][j+n];
}
dc.AddEdge(t,s,inf);
if(flag) { puts("IMPOSSIBLE"); continue; }
int sum=;
FOR(i,,t) {
if(in[i]>) dc.AddEdge(S,i,in[i]),sum+=in[i];
if(in[i]<) dc.AddEdge(i,T,-in[i]);
}
if(sum!=dc.MaxFlow(S,T)) { puts("IMPOSSIBLE"); continue; }
else {
FOR(i,,n) FOR(j,,m) {
printf("%d",dc.es[cur].flow+down[i][j+n]);
if(j!=m) putchar(' '); else puts("");
cur+=;
}
}
}
return ;
}

poj2396 Budget(有源汇上下界可行流)的更多相关文章

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

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

  2. poj2396 Budget&&ZOJ1994 Budget[有源汇上下界可行流]

    Budget Time Limit: 5 Seconds      Memory Limit: 32768 KB      Special Judge We are supposed to make ...

  3. 有源汇上下界可行流(POJ2396)

    题意:给出一个n*m的矩阵的每行和及每列和,还有一些格子的限制,求一组合法方案. 源点向行,汇点向列,连一条上下界均为和的边. 对于某格的限制,从它所在行向所在列连其上下界的边. 求有源汇上下界可行流 ...

  4. 计蒜客 31447 - Fantastic Graph - [有源汇上下界可行流][2018ICPC沈阳网络预赛F题]

    题目链接:https://nanti.jisuanke.com/t/31447 "Oh, There is a bipartite graph.""Make it Fan ...

  5. poj2396有源汇上下界可行流

    题意:给一些约束条件,要求算能否有可行流,ps:刚开始输入的是每一列和,那么就建一条上下界相同的边,这样满流的时候就一定能保证流量相同了,还有0是该列(行)对另一行每个点都要满足约束条件 解法:先按无 ...

  6. 算法复习——有源汇上下界可行流(bzoj2396)

    题目: Description We are supposed to make a budget proposal for this multi-site competition. The budge ...

  7. ZOJ1994有源汇上下界可行流

    http://fastvj.rainng.com/contest/236779#problem/G Description: n 行 m 列 给你行和 与 列和 然后有Q个限制,表示特定单元格元素大小 ...

  8. bzoj 2406 矩阵 —— 有源汇上下界可行流

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2406 这题,首先把题目那个式子的绝对值拆成两个限制,就成了网络流的上下界: 有上下界可行流原 ...

  9. bzoj千题计划158:bzoj2406: 矩阵(有源汇上下界可行流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2406 设矩阵C=A-B 最小化 C 一行或一列和的最大值 整体考虑一行或者一列的和 二分最大值 这样 ...

随机推荐

  1. Hibernate逍遥游记-第3章对象-关系映射基础-access="field"、dynamic-insert、dynamic-update、formula、update=false

    1. package mypack; import java.util.*; public class Monkey{ private Long id; private String firstnam ...

  2. HackDemo.java

    import java.io.*; import java.awt.*; public class HackDemo{ public static void main(String args[]) t ...

  3. 门面(Facade)模式(转)

    转载:http://www.cnblogs.com/skywang/articles/1375447.html 外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式. ...

  4. 47. Permutations II

    题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...

  5. 写Java程序让Jvm崩溃

    package jvm; public class HeapCrash { public static void main(String[] args) { //Object[] o = {“abc” ...

  6. nodejs抓网易NBA数据

    var http = require("http");var cheerio = require("cheerio"); var url = "htt ...

  7. Android动画效果translate、scale、alpha、rotate

    overridePendingTransition只支持android 2.0以上版本,动画效果在anim目录下的xml文件中定义,在程序中用AnimationUtils.loadAnimation( ...

  8. C#路径/文件/目录/I/O常见操作汇总<转载>

    文件操作是程序中非常基础和重要的内容,而路径.文件.目录以及I/O都是在进行文件操作时的常见主题,这里想把这些常见的问题作个总结,对于每个问题,尽量提供一些解决方案,即使没有你想要的答案,也希望能提供 ...

  9. json格式的字符串使用string.Format()方法报错:输入字符串的格式不正确

    解决:把大括号转义一下就可以了啊,大括号的转义是两个{{  结尾是}}     今天看同事写的代码,发现他在使用string.format拼接类似json格式的数据时,大括号多了一对,感觉不对就查了查 ...

  10. [反汇编练习] 160个CrackMe之019

    [反汇编练习] 160个CrackMe之018. 本系列文章的目的是从一个没有任何经验的新手的角度(其实就是我自己),一步步尝试将160个CrackMe全部破解,如果可以,通过任何方式写出一个类似于注 ...