[poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流
poj原题
zoj原题
//注意zoj最后一行不要多输出空行
现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出、列代表不同赛区支出的矩阵。组委会曾经开会讨论过各类支出的总和,以及各赛区所需支出的总和。另外,组委会还讨论了一些特殊的约束条件。组委会的任务是制定一个满足所有约束条件且行列和满足要求的预算。
有源汇的上下界可行流。
1、建原图(对于上界Max和下界Min的边连边为Max-Min,像无源汇一样记录extra)
2、在t和s(原图)见连接一条inf的边,使原图变为无源汇
3、建虚拟源汇S和T,按无源汇建图
4、跑最大流
5、判断是否可行(==sum)
#include<cstdio>
#include<algorithm>
#define N 250
#define M 100010
#define inf 0x3f3f3f3f
#define fir first
#define sec second
using namespace std;
struct hhh
{
int to,w,next,f,lower;
}edge[M];
int cnt=1,head[N],dis[N],cur[N];
int TT,n,m,s,t,ans,sum,q[N],r,extra[N],A[N][N];
int Q,a,b,x;
char c[3];
pair <int,int> g[N][N];
int read()
{
int ans=0,fu=1;
char j=getchar();
for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
}
void init()
{
ans=sum=0;
cnt=1;
for (int i=1;i<=n+m+5;i++)
head[i]=extra[i]=0;
}
int add(int u,int v,int w,int p)
{
edge[++cnt].to=v;edge[cnt].next=head[u];edge[cnt].w=w;edge[cnt].f=0;edge[cnt].lower=p;head[u]=cnt;
edge[++cnt].to=u;edge[cnt].next=head[v];edge[cnt].w=0;edge[cnt].f=0;edge[cnt].lower=p;head[v]=cnt;
return cnt-1;
}
bool ADD(int u,int v,char d,int w)
{
pair <int,int> &now=g[u][v];
if (d=='=')
{
if (now.fir<=w && w<=now.sec) now=make_pair(w,w);
else return 0;
}
else if (d=='>')
{
w++;
if (now.sec>=w) now.fir=max(now.fir,w);
else return 0;
}
else
{
w--;
if (now.fir<=w) now.sec=min(now.sec,w);
else return 0;
}
return 1;
}
bool bfs(int S,int T)
{
for (int i=0;i<=T;i++)
cur[i]=head[i],dis[i]=-1;
dis[S]=1;
q[r=1]=S;
for (int l=1;l<=r;l++)
{
int u=q[l];
for (int i=head[u],v;i;i=edge[i].next)
if (edge[i].w>edge[i].f && dis[v=edge[i].to]==-1)
{
dis[v]=dis[u]+1;
q[++r]=v;
if (v==T) return 1;
}
}
return 0;
}
int dfs(int u,int flow,int T)
{
if (u==T || flow==0) return flow;
int ret=0,delta;
for (int &i=cur[u],v;i;i=edge[i].next)
if (edge[i].w-edge[i].f && dis[v=edge[i].to]==dis[u]+1)
{
delta=dfs(v,min(edge[i].w-edge[i].f,flow-ret),T);
if (delta)
{
edge[i].f+=delta;
edge[i^1].f-=delta;
ret+=delta;
if (ret==flow) break;
}
}
if (ret!=flow) dis[u]=-1;
return ret;
}
int dinic(int S,int T)
{
int ans=0;
while (bfs(S,T))
ans+=dfs(S,inf,T);
return ans;
}
bool solve()
{
for (int i=1;i<=n;i++)
for (int j=1,x,y;j<=m;j++)
{
x=g[i][j].fir;y=g[i][j].sec;
A[i][j]=add(i,n+j,y-x,x);
extra[i]-=x;extra[n+j]+=x;
}
add(t,s,inf,0);
int ss=t+1,tt=t+2,sum=0;
for (int i=s;i<=t;i++)
{
if (extra[i]>0) add(ss,i,extra[i],0),sum+=extra[i];
if (extra[i]<0) add(i,tt,-extra[i],0);
}
int flow=dinic(ss,tt);
return flow==sum;
}
int main()
{
TT=read();
while (TT--)
{
n=read();
m=read();
s=0;
t=n+m+1;
init();
for (int i=1;i<=n;i++) x=read(),add(s,i,0,x),extra[s]-=x,extra[i]+=x;
for (int i=1;i<=m;i++) x=read(),add(n+i,t,0,x),extra[n+i]-=x,extra[t]+=x;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
g[i][j]=make_pair(0,inf);
Q=read();
bool flag=1;
while (Q--)
{
a=read();
b=read();
scanf("%s",c);
x=read();
if (!a && !b)
{
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
flag&=ADD(i,j,c[0],x);
}
else if (!a)
for (int i=1;i<=n;i++)
flag&=ADD(i,b,c[0],x);
else if (!b)
for (int i=1;i<=m;i++)
flag&=ADD(a,i,c[0],x);
else flag&=ADD(a,b,c[0],x);
}
if (!flag || !solve())
puts("IMPOSSIBLE");
else
{
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
printf("%d%c",edge[A[i][j]].f+edge[A[i][j]].lower," \n"[j==m]);
}
}
return 0;
}
[poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流的更多相关文章
- POJ 2396 Budget (有源汇有上下界最大流)
题意:给定一个矩阵的每行的和和每列的和,以及每个格子的限制,让你求出原矩阵. 析:把行看成X,列看成Y,其实就是二分图,然后每个X到每个Y边一条边,然后加一个超级源点和汇点分别向X和Y连边,这样就形成 ...
- 【 POJ - 3801】Crazy Circuits(有源汇、上下界最小流)
Description You’ve just built a circuit board for your new robot, and now you need to power it. Your ...
- ZOJ 3229 Shoot the Bullet(有源汇的上下界最大流)
Description Gensokyo is a world which exists quietly beside ours, separated by a mystical border. It ...
- LOJ116 - 有源汇有上下界最大流
原题链接 Description 模板题啦~ Code //有源汇有上下界最大流 #include <cstdio> #include <cstring> #include & ...
- 【Loj116】有源汇有上下界最大流(网络流)
[Loj116]有源汇有上下界最大流(网络流) 题面 Loj 题解 模板题. #include<iostream> #include<cstdio> #include<c ...
- loj #116. 有源汇有上下界最大流
题目链接 有源汇有上下界最大流,->上下界网络流 注意细节,重置cur和dis数组时,有n+2个点 #include<cstdio> #include<algorithm> ...
- loj #117. 有源汇有上下界最小流
题目链接 有源汇有上下界最小流,->上下界网络流 注意细节,边数组也要算上后加到SS,TT边. #include<cstdio> #include<algorithm> ...
- LOJ.117.[模板]有源汇有上下界最小流(Dinic)
题目链接 有源汇有上下界最小流 Sol1. 首先和无源汇网络流一样建图,求SS->TT最大流: 然后连边(T->S,[0,INF]),再求一遍SS->TT最大流,答案为新添加边的流量 ...
- 【LOJ116】有源汇有上下界最大流(模板题)
点此看题面 大致题意: 给你每条边的流量上下界,让你先判断是否存在可行流.若存在,则输出最大流. 无源汇上下界可行流 在做此题之前,最好先去看看这道题目:[LOJ115]无源汇有上下界可行流. 大致思 ...
随机推荐
- Hive初识(二)
Hive分区 Hive组织表到分区.它是将一个表到基于分区列,如日期,城市和部门的值相关方式.使用分区,很容易对数据进行部分查询. 表或分区是细分成桶,以提供额外的结构,可以使用更高效的查询的数据.桶 ...
- Python的scrapy之爬取51job网站的职位
今天老师讲解了Python中的爬虫框架--scrapy,然后带领我们做了一个小爬虫--爬取51job网的职位信息,并且保存到数据库中 用的是Python3.6 pycharm编辑器 爬虫主体: im ...
- 中恳中笨 搭建flask封装环境
话不多说,先干再说..... 打开pycharm,创建一个关于flask的项目 2.创建一个App的文件包 3.把staic和templates文件包拖进App里 4.把app.py文件改为manag ...
- 爬虫之request模块高级
一.cookie&session cookie:服务器端使用cookie来记录客户端的状态信息 实现流程: 执行登陆操作(获取cookie) 在发起个人主页请求时,需要将cookie携带到该请 ...
- 015---Django的forms组件
Django form表单 Form介绍 我们之前在HTML页面中利用form表单向后端提交数据时,都会写一些获取用户输入的标签并且用form标签把它们包起来. 与此同时我们在好多场景下都需要对用 ...
- 初步学习pg_control文件之十五
接前文 初步学习pg_control文件之十四 再看如下这个: int MaxConnections; 应该说,它是一个参考值,在global.c中有如下定义 /* * Primary determ ...
- spring、spring-data-redis整合使用
一.Redis是一个开源的使用ANSI C语言编写.支持网络.可基于内存亦可持久化的日志型.Key-Value数据库,并提供多种语言的API. 从2010年3月15日起,Redis的开发工作由VMwa ...
- Java输出日历写法
package TestString_2; import java.text.ParseException;import java.util.Calendar;import java.util.Gre ...
- 多个Target的使用
背景介绍 开发过程中,我们会在内网搭建一个测试服务器,开发.测试都是在内网进行的.这样产生脏数据不会影响外网的服务器.外网服务器只有最后发布时才会进行一些必要的测试. 还有就是要对同一份代码生成不同的 ...
- loadrunner创建测试脚本运行无响应 不记录脚本
解决一运行User Generator直接程序卡死无响应的办法. (1)“我的电脑”点右键->属性->高级 点选“性能”中的“设置” (2)打开对话框后,进入“数据执行保护”,如果空白框中 ...