POJ 2396 Budget【网络流】
题意:
cas //测试数据组数
n m //行数 列数
a1 a2 ... an //每行的和
b1 b2 ... bn //每列的和
q //操作数量
//接下来q行
a b >/</= c //若a为0则表示一整列,b为0表示一整行,否则a代表第几行,b代表第几列,操作表示选中区域或者某个元素要严格大于或者严格小于或者等于c
求:判断是否存在合法矩阵,如果存在输出任一合法矩阵(每个元素都要求非负),否则输出“IMPOSSIBLE”
思路:
上马基的时候自己想了想,首先是各种基础的操作判断给出的各项限制之间有没有矛盾,然后最大流跑下判断。
根据给出的限制,每个元素都有下限和上限,然后把下限单独从总的流中拿出来,用剩下的区间的值跑下最大流,看最后最大流的流量是否是去除每个元素下限之后的所有的元素的和。
坑:
1.这题是多组输入数据,如果判断出不可能直接return 0;这种愚蠢的行为出现在我的代码上了。已经无力吐槽。
2.建图。一开始我的建图的方法是每个元素在图中表示一个点,然后左端是表示行的点右端是表示列的点,然后连起来。当时感觉好像还不错,保证每个点对行和列的贡献是一样的...然后就开始各种超时了,一直找原因,直到找到大神的代码...真是tmsb,其实这种点的度数为2而且两条边的容量是相等的情况下,完全可以把这点省略,去除了n*m个点就过了...
不管怎么样,有坑都是好事。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<string.h>
#include<vector>
#define MAXN 4050
#define MAXM 40050
using namespace std;
const int inf=0x3f3f3f3f;
int hang[],lie[];
int mmax[][],mmin[][];
struct Edge
{
int v,c,f,nx;
Edge() {}
Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {}
} E[MAXM];
int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],sz;
void init()
{
sz=;
memset(G,-,sizeof(G));
}
void add_edge(int u,int v,int c)
{
E[sz]=Edge(v,c,,G[u]);
G[u]=sz++;
E[sz]=Edge(u,,,G[v]);
G[v]=sz++;
}
bool bfs(int S,int T)
{
static int Q[MAXN];
memset(dis,-,sizeof(dis));
dis[S]=;
Q[]=S;
for (int h=,t=,u,v,it; h<t; ++h)
{
for (u=Q[h],it=G[u]; ~it; it=E[it].nx)
{
if (dis[v=E[it].v]==-&&E[it].c>E[it].f)
{
dis[v]=dis[u]+;
Q[t++]=v;
}
}
}
return dis[T]!=-;
}
int dfs(int u,int T,int low)
{
if (u==T) return low;
int ret=,tmp,v;
for (int &it=cur[u]; ~it&&ret<low; it=E[it].nx)
{
if (dis[v=E[it].v]==dis[u]+&&E[it].c>E[it].f)
{
if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f)))
{
ret+=tmp;
E[it].f+=tmp;
E[it^].f-=tmp;
}
}
}
if (!ret) dis[u]=-;
return ret;
}
int dinic(int S,int T)
{
int maxflow=,tmp;
while (bfs(S,T))
{
memcpy(cur,G,sizeof(G));
while (tmp=dfs(S,T,inf)) maxflow+=tmp;
}
return maxflow;
}
int main()
{
int cas;
scanf("%d",&cas);
while(cas--)
{
bool ok=;
memset(mmin,,sizeof(mmin));
init();
int n,m,x,y,z,k;
char typ[];
scanf("%d%d",&n,&m);
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
{
mmax[i][j]=inf;
}
}
for(int i=; i<=n; i++)
{
scanf("%d",&hang[i]);
}
for(int i=; i<=m; i++)
{
scanf("%d",&lie[i]);
}
scanf("%d",&k);
for(int i=; i<=k; i++)
{
scanf("%d%d%s%d",&x,&y,typ,&z);
if(x==)
{
if(y==)
{
for(int j=; j<=n; j++)
{
for(int kk=; kk<=m; kk++)
{
if(typ[]=='<')
{
mmax[j][kk]=min(mmax[j][kk],z-);
}
else if(typ[]=='>')
{
mmin[j][kk]=max(mmin[j][kk],z+);
}
else
{
mmax[j][kk]=min(mmax[j][kk],z);
mmin[j][kk]=max(mmin[j][kk],z);
}
}
}
}
else
{
for(int j=; j<=n; j++)
{
if(typ[]=='<')
{
mmax[j][y]=min(mmax[j][y],z-);
}
else if(typ[]=='>')
{
mmin[j][y]=max(mmin[j][y],z+);
}
else
{
mmax[j][y]=min(mmax[j][y],z);
mmin[j][y]=max(mmin[j][y],z);
}
}
}
}
else
{
if(y==)
{
for(int j=; j<=m; j++)
{
if(typ[]=='<')
{
mmax[x][j]=min(mmax[x][j],z-);
}
else if(typ[]=='>')
{
mmin[x][j]=max(mmin[x][j],z+);
}
else
{
mmax[x][j]=min(mmax[x][j],z);
mmin[x][j]=max(mmin[x][j],z);
}
}
}
else
{
if(typ[]=='<')
{
mmax[x][y]=min(mmax[x][y],z-);
}
else if(typ[]=='>')
{
mmin[x][y]=max(mmin[x][y],z+);
}
else
{
mmax[x][y]=min(mmax[x][y],z);
mmin[x][y]=max(mmin[x][y],z);
}
}
}
}
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
{
if(mmax[i][j]<||mmax[i][j]<mmin[i][j])
{
ok=;
break;
}
hang[i]-=mmin[i][j];
lie[j]-=mmin[i][j];
if(hang[i]<||lie[j]<)
{
ok=;
break;
}
}
}
int ans1,ans2;
if(ok){
for(int i=; i<=n; i++)
{
add_edge(,i,hang[i]);
}
for(int i=n+; i<=m+n; i++)
{
add_edge(i,n+m+,lie[i-n]);
}
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
{
add_edge(i,n+j,mmax[i][j]-mmin[i][j]);
}
}
ans1=,ans2=;
for(int i=; i<=n; i++)
{
ans1+=hang[i];
}
for(int i=; i<=m; i++)
{
ans2+=lie[i];
}
if(ans1!=ans2)
{
ok=;
}}
if(ok){
if(dinic(,m+n+)==ans1)
{
memcpy(cur,G,sizeof(G));
for(int i=; i<=n; i++)
{
for(int j=; j<=m; j++)
{
int v;
for (int it=cur[i]; ~it; it=E[it].nx)
{
v=E[it].v;
if (v==n+j)
{
printf("%d ",E[it].f+mmin[i][j]);
break;
}
}
}
puts("");
}
}
else
{
ok=;
}}
if(ok==)puts("IMPOSSIBLE");
if(cas)puts("");
}
}
POJ 2396 Budget【网络流】的更多相关文章
- POJ 2396 Budget 有上下界的网络流
POJ 2396 Budget 题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测.矩阵规模小于200*20. 网络流的模型是显而易见的,不过对 ...
- poj 2396 Budget 边容量有上下界的最大流
题意: 给一个矩阵的每行和及每列和,在给一些行列或点的限制条件.求一个满足的矩阵. 分析: 转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法. 代码: //poj 2396 / ...
- POJ 2396 Budget(有源汇上下界网络流)
Description We are supposed to make a budget proposal for this multi-site competition. The budget pr ...
- POJ 2396 Budget ——有上下界的网络流
给定矩阵的每行每列的和,和一些大于小于等于的限制.然后需要求出一组可行解. 上下界网络流. 大概的思想就是计算出每一个点他需要强行流入或者流出的量,然后建出超级源点和汇点,然后删除下界,就可以判断是否 ...
- poj 2396 Budget【有上下界的网络流】
第一步:建立无源汇有上下界的网络模型 每行 i 作为一个点并连边(s, i, Ri, Ri),每列 j 作为一个点并连边(j, t, Cj, Cj),设 Uij, Lij 分别表示第 i 行第 j 列 ...
- POJ 2396 Budget (上下界网络流有源可行流)
转载: http://blog.csdn.net/axuan_k/article/details/47297395 题目描述: 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表 ...
- poj 2396 Budget
一个m行n列的矩阵,给出每行每列中元素的和,以及对一些格子的大小限制,求一个可行方案,输出矩阵. 大小限制形如:严格大于i,严格小于i,等于i. 1<=m<=200.1<=n< ...
- POJ 2396 Budget (有源汇有上下界最大流)
题意:给定一个矩阵的每行的和和每列的和,以及每个格子的限制,让你求出原矩阵. 析:把行看成X,列看成Y,其实就是二分图,然后每个X到每个Y边一条边,然后加一个超级源点和汇点分别向X和Y连边,这样就形成 ...
- [poj] 2396 [zoj] 1994 budget || 有源汇的上下界可行流
poj原题 zoj原题 //注意zoj最后一行不要多输出空行 现在要针对多赛区竞赛制定一个预算,该预算是一个行代表不同种类支出.列代表不同赛区支出的矩阵.组委会曾经开会讨论过各类支出的总和,以及各赛区 ...
随机推荐
- 【转】 CSS3阴影 box-shadow的使用和技巧总结
text-shadow是给文本添加阴影效果,box-shadow是给元素块添加周边阴影效果.随着html5和CSS3的普及,这一特殊效果使用越来越普遍. 基本语法是{box-shadow:[inset ...
- 由浅入深探究mysql索引结构原理、性能分析与优化 转
第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1. 简单介绍B-tree B+ tree树 2. MyisAM索引结构 3. Annode索引结构 4. MyisAM索引与Inno ...
- Android Studio 单元测试
测试的种类 按岗位划分 黑盒测试:测试逻辑业务 白盒测试:测试逻辑方法 按测试粒度分 方法测试:function test 单元测试:unit test 集成测试:integration test 系 ...
- Angular学习(3)- 双向梆定
示例代码: <!DOCTYPE html> <html ng-app="MyApp"> <head> <title>Study 3& ...
- 14款经典的MySQL客户端软件
1. EMS MySQL Manager 强大的mysql管理工具,允许用户通过图形界面创建或编辑数据库对象,并提供通过sql语句管理用户和权限,通过图形界面建立sql语句,自动生成html格式的数据 ...
- Web通过JS调用客户端
代码实现==> <html> <head> <script language="javascript"> function Run(str ...
- "unresolved external symbol __imp__WSACleanup@0"
编译时出现这种问题怎么解决:"unresolved external symbol __imp__WSACleanup@0"出现此类问题一般是ws2_32.lib这个lib没有li ...
- VS 使用Sql Server 数据库增删改查
/// <summary> /// 执行查询语句,返回DataSet /// </summary> /// <param name="SQLString&quo ...
- 数据库随机取n条记录
SQL Server SELECT TOP N * FROM 表名 ORDER BY NEWID() My SQL SELECT * FROM 表名 ORDER BY RAND() ...
- Top 6 Programming Languages for Mobile App Development
Mobile application development industry in the last five years have multiplied in leaps and bounds, ...