POJ2396_Budget
题意为给一个矩形数字阵,给出一些限制条件,包括每行和每列的和,还有一些位置的数值范围,求出满足情况的一个。
首先建图,源点->行和->列和->汇点,显然,行和列之间的边为那个数字的大小,只要我们能够找到一个满足大小条件的,且使的两边的和满流的流量方案就可以了。
由于存在下界(上界其实就是边的容量),根据图的特殊性,我们可以先在那边的相连的两条边都减去这个下界,这样就变成了一条只有上界的边了。
召唤代码君:
#include <iostream>
#include <cstring>
#include <cstdio>
#define maxn 1022
#define maxm 844442
typedef long long ll;
using namespace std; const ll inf=~0U>>;
ll to[maxm],next[maxm],c[maxm],first[maxn],edge;
ll fmin[maxn][maxn],fmax[maxn][maxn],sr[maxn],sc[maxn];
ll d[maxn],tag[maxn],TAG=;
ll Q[maxm],bot,top;
ll ans[maxn][maxn];
bool can[maxn];
ll n,m,s,t,T,R,sumr,sumc; void _init()
{
s=,t=n+m+,edge=-,sumr=sumc=;
for (ll i=s; i<=t; i++) first[i]=-;
for (ll i=; i<=n; i++) sr[i]=;
for (ll i=; i<=m; i++) sc[i]=;
for (ll i=; i<=n; i++)
for (ll j=; j<=m; j++) ans[i][j]=,fmin[i][j]=,fmax[i][j]=inf;
} void minsize(ll x,ll y,ll dn,ll up)
{
fmin[x][y]=max(fmin[x][y],dn);
fmax[x][y]=min(fmax[x][y],up);
} bool check()
{
for (ll i=; i<=n; i++)
for (ll j=; j<=m; j++)
{
if (fmax[i][j]<) return false;
sr[i]-=fmin[i][j],sc[j]-=fmin[i][j];
sumr-=fmin[i][j],sumc-=fmin[i][j];
fmax[i][j]-=fmin[i][j];
if (fmax[i][j]< || sr[i]< || sc[j]<) return false;
}
return sumr==sumc;
} void addedge(ll U,ll V,ll W)
{
edge++;
to[edge]=V,c[edge]=W,next[edge]=first[U],first[U]=edge;
edge++;
to[edge]=U,c[edge]=,next[edge]=first[V],first[V]=edge;
} bool bfs()
{
Q[bot=top=]=t,tag[t]=++TAG,d[t]=,can[t]=false;
while (bot<=top)
{
ll cur=Q[bot++];
for (ll i=first[cur]; i!=-; i=next[i])
if (c[i^] && tag[to[i]]!=TAG)
{
tag[to[i]]=TAG,d[to[i]]=d[cur]+;
can[to[i]]=false,Q[++top]=to[i];
if (to[i]==s) return true;
}
}
return false;
} ll dfs(ll cur,ll num)
{
if (cur==t) return num;
ll tmp=num,k;
for (ll i=first[cur]; i!=-; i=next[i])
if (c[i] && d[to[i]]==d[cur]- && tag[to[i]]==TAG && !can[to[i]])
{
k=dfs(to[i],min(c[i],num));
if (k) num-=k,c[i]-=k,c[i^]+=k;
if (!num) break;
}
if (num) can[cur]=true;
return tmp-num;
} ll maxflow()
{
ll tot=;
while (bfs()) tot+=dfs(s,~0U>>);
return tot;
} int main()
{
char S[];
ll x,y,z,cas=,up,dn;
scanf("%I64d",&T);
while (T--)
{
scanf("%I64d%I64d",&n,&m);
_init();
for (ll i=; i<=n; i++) scanf("%I64d",&sr[i]),sumr+=sr[i];
for (ll i=; i<=m; i++) scanf("%I64d",&sc[i]),sumc+=sc[i];
scanf("%I64d",&R);
while (R--)
{
scanf("%I64d%I64d%s%I64d",&x,&y,S,&z);
if (S[]=='=') up=z,dn=max(0LL,z);
else if (S[]=='>') up=inf,dn=max(0LL,z+);
else up=z-,dn=;
if (x== && y==)
{
for (ll i=; i<=n; i++)
for (ll j=; j<=m; j++) minsize(i,j,dn,up);
}
else if (x==)
{
for (ll i=; i<=n; i++) minsize(i,y,dn,up);
}
else if (y==)
{
for (ll j=; j<=m; j++) minsize(x,j,dn,up);
}
else minsize(x,y,dn,up);
}
if (cas++) puts("");
if (!check())
{
puts("IMPOSSIBLE");
continue;
}
for (ll i=; i<=n; i++) addedge(s,i,sr[i]);
for (ll j=; j<=m; j++) addedge(n+j,t,sc[j]);
for (ll i=; i<=n; i++)
for (ll j=; j<=m; j++)
if (fmax[i][j]>) addedge(i,n+j,fmax[i][j]);
/*
for (int i=1; i<=n; i++)
{
cout<<" hehe : ";
for (int j=1; j<=m; j++) cout<<fmin[i][j]<<"("<<fmax[i][j]<<") ... ";
cout<<endl;
}
*/
if (maxflow()!=sumr)
{
puts("IMPOSSIBLE");
continue;
}
for (ll i=n+n+m+m; i<=edge; i+=)
{
x=to[i+],y=to[i]-n;
ans[x][y]=c[i+];
}
for (ll i=; i<=n; i++)
{
printf("%I64d",ans[i][]+fmin[i][]);
for (ll j=; j<=m; j++) printf(" %I64d",ans[i][j]+fmin[i][j]);
printf("\n");
}
}
return ;
}
POJ2396_Budget的更多相关文章
随机推荐
- 用ping命令来模拟traceroute的功能
ping -n 1 -r 9 qq.com 正在 Ping qq.com [163.177.65.160] 具有 32 字节的数据:来自 163.177.65.160 的回复: 字节=32 时间=11 ...
- (Array)27. Remove Element
Given an array and a value, remove all instances of that value in place and return the new length. D ...
- Ubuntu中启用关闭Network-manager网络设置问题!
Ubuntu中启用关闭Network-manager网络设置问题! [Server版本] 在UbuntuServer版本中,因为只存有命令行模式,所以要想进行网络参数设置,只能通过修改/etc/net ...
- 【整理】更改MSSQL默认字符集
记录所有应用到 SQL Server 实例和当前排序规则的 Service Pack 和修补程序: SELECT SERVERPROPERTY('ProductVersion ') AS Produc ...
- iOS开发中的4种数据持久化方式【二、数据库 SQLite3、Core Data 的运用】
在上文,我们介绍了ios开发中的其中2种数据持久化方式:属性列表.归档解档.本节将继续介绍另外2种iOS持久化数据的方法:数据库 SQLite3.Core Data 的运 ...
- ES6中的Class
对于javascript来说,类是一种可选(而不是必须)的设计模式,而且在JavaScript这样的[[Prototype]] 语言中实现类是很蹩脚的. 这种蹩脚的感觉不只是来源于语法,虽然语法是很重 ...
- 【Tree 3】树形结构数据加载的思考
前面两篇文章,分别介绍了使用递归和非递归算法加载树形结构数据的方式,本篇文章,则是自己闲下来的时候,进行的一点小思考. 一.什么地方会用到树形结构 刚开始一看到这种结构的时候,最先是想到了家谱.家谱就 ...
- Orcle常用语句
在SQLPlus界面的操作语句: 查看\设置每行内显示的字符数:show\set linesize [linesize] 查看\设置一次显示的行数:show\set pagesize [pagesiz ...
- {matlab}取二值图像centroid几种方法性能比较
试验很简单,取二值图像的质心,三种方法做比较 1.完全采用矩阵性能不做任何循环操作,对find后的值进行除法与取余操作,从而得到centroid 2.完全采用循环操作,最简单明了 3.结合1,2,对每 ...
- makefile多目录的.c 格式.cpp混合编译
# # c.cpp混合编译的makefile模板 # # BIN = test.exe CC = gcc CPP = g++ #这里只加入库头文件路径及库路径 INCS = -I"c:/mi ...