POJ 2396  Budget

题意简述:给定矩阵(每个元素都是非负整数)各行各列的和,并且限制其中的某些元素,给出一个可行解,特殊评测。矩阵规模小于200*20。

网络流的模型是显而易见的,不过对于这道题,我们要添加两次源和汇。

第一次添加s连接每一行,t连接每一列,容量上下线都是这行或这列的和。

第二次对每条有容量限制的边(u,v)添加 (ss,v)和( u,tt)容量均为( u,v)的下限。

第三次添加(t,s)容量无穷。

对(ss,tt)求最大流,若ss出发和进入tt的边均满流则有解,并且可以直接输出解。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxm=200+50,INF=1e+8;
int k,ans[maxm][maxm],cap[maxm][maxm],flow[maxm][maxm],low[maxm][maxm],up[maxm][maxm],n,m;
vector<int> next[maxm]; int d[maxm],fa[maxm],cur[maxm];
bool vis[maxm];
bool bfs(int s,int t)
{
memset(vis,0,sizeof(vis));
memset(d,0,sizeof(d));
queue<int>q;
vis[s]=true;q.push(s);
while(!q.empty())
{
int np=q.front();q.pop();
for(int i=0;i<next[np].size();i++)
{
int ne=next[np][i];
if(cap[np][ne]<=flow[np][ne]||vis[ne])continue;
q.push(ne);
vis[ne]=true;
d[ne]=d[np]+1;
}
}
return vis[t];
} int dfs(int now,int t,int flo)
{
if(now==t||flo==0)return flo;
int floww=0;
for(int i=cur[now];i<next[now].size();i++)
{
int np=next[now][i];
if(d[np]!=d[now]+1)continue;
if(cap[now][np]<=flow[now][np])continue;
int fn=dfs(np,t,min(flo,cap[now][np]-flow[now][np]));
flow[now][np]+=fn;
flow[np][now]-=fn;
floww+=fn;
flo-=fn;
if(flo==0)break;
cur[now]++;
}
return floww;
}
int dinic(int s,int t)
{
int ans=0;
while(bfs(s,t))
{
memset(cur,0,sizeof(cur));
ans+=dfs(s,t,INF);
}
return ans;
}
void find(int s,int t)
{
memset(d,0,sizeof(d));
d[s]=INF;
queue<int>q;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int i=0;i<next[u].size();i++)
{
int nextp=next[u][i];
if(d[nextp]!=0||(cap[u][nextp]-flow[u][nextp])<=0)continue;
d[nextp]=min(d[u],(cap[u][nextp]-flow[u][nextp]));
q.push(nextp);
fa[nextp]=u;
if(nextp==t)
{
while(!q.empty())q.pop();
return ;
}
}
}
}
int E_K(int s,int t)
{
int ans=0;
memset(fa,0,sizeof(fa));
while(true)
{
find(s,t);
ans+=d[t];
if(d[t]==0)break;
for(int i=t;i!=s;i=fa[i])
{
flow[fa[i]][i]+=d[t];
flow[i][fa[i]]-=d[t];
}
}
return ans;
} void addedge(int a,int b,vector<int> next[])
{
next[a].push_back(b);
next[b].push_back(a);
return ;
}
int main()
{
int N;
int s=249,t=s-1,ss=t-1,tt=ss-1;
scanf("%d",&N);
for(int ii=1;ii<=N;ii++)
{ for(int i=0;i<maxm;i++)
while(next[i].size()>0)next[i].pop_back();
memset(cap,0,sizeof(cap));memset(flow,0,sizeof(flow));
memset(low,0,sizeof(low));memset(up,0,sizeof(up));
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
int a;scanf("%d",&a);
cap[s][i]=0;cap[ss][i]+=a;cap[s][tt]+=a;
addedge(s,i,next);addedge(ss,i,next);addedge(i,tt,next);
for(int j=201;j<=200+n;j++)
{
addedge(i,j,next);
up[i][j]=a;
}
}
addedge(s,tt,next);
for(int i=201;i<=200+n;i++)
{
int a;scanf("%d",&a);
cap[i][t]=0;cap[ss][t]+=a;cap[i][tt]+=a;
addedge(i,t,next);addedge(i,tt,next);addedge(i,ss,next);
for(int j=1;j<=m;j++)
up[j][i]=min(up[j][i],a);
}
addedge(ss,t,next);
int k;
scanf("%d",&k);
for(int iii=0;iii<k;iii++)
{
int a,b,c;char t;
scanf("%d%d",&a,&b);t=getchar();t=getchar();scanf("%d",&c);
int ia,ib,ja,jb;
if(a==0){ia=1;ib=m;}
else {ia=ib=a;}
if(b==0){ja=201;jb=200+n;}
else{ja=jb=(200+b);}
for(int i=ia;i<=ib;i++)
for(int j=ja;j<=jb;j++)
{
if(t=='=')
{
up[i][j]=min(up[i][j],c);low[i][j]=max(low[i][j],c);
}
if(t=='>')
{
low[i][j]=max(low[i][j],c+1);
}
if(t=='<')
{
up[i][j]=min(up[i][j],c-1);
}
}
}
for(int i=1;i<=m;i++)
for(int j=201;j<=200+n;j++)
{
cap[i][j]=up[i][j]-low[i][j];
cap[ss][j]+=low[i][j];
cap[i][tt]+=low[i][j];
}
next[t].push_back(s);cap[t][s]=INF;
dinic(ss,tt);
bool impo=false;
for(int i=1;i<=m;i++)
{
if(flow[ss][i]!=cap[ss][i]){impo=true;break;}
if(flow[i][tt]!=cap[i][tt]){impo=true;break;}
}
for(int j=201;j<=200+n;j++)
{
if(flow[ss][j]!=cap[ss][j]){impo=true;break;}
if(flow[j][tt]!=cap[j][tt]){impo=true;break;}
}
if(flow[s][tt]!=cap[s][tt]){impo=true;}
if(flow[ss][t]!=cap[ss][t]){impo=true;}
if(impo){printf("IMPOSSIBLE\n\n");continue;}
for(int i=1;i<=m;i++)
{ for(int j=201;j<n+200;j++)
{
printf("%d ",flow[i][j]+low[i][j]);
}
printf("%d\n",flow[i][200+n]+low[i][200+n]);
}
printf("\n");
}
return 0;
}

  

                                    

POJ 2396 Budget 有上下界的网络流的更多相关文章

  1. POJ 2396 Budget ——有上下界的网络流

    给定矩阵的每行每列的和,和一些大于小于等于的限制.然后需要求出一组可行解. 上下界网络流. 大概的思想就是计算出每一个点他需要强行流入或者流出的量,然后建出超级源点和汇点,然后删除下界,就可以判断是否 ...

  2. poj 2396 Budget 边容量有上下界的最大流

    题意: 给一个矩阵的每行和及每列和,在给一些行列或点的限制条件.求一个满足的矩阵. 分析: 转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法. 代码: //poj 2396 / ...

  3. 【POJ2396】Budget(上下界网络流)

    Description We are supposed to make a budget proposal for this multi-site competition. The budget pr ...

  4. ACM/ICPC 之 有流量上下界的网络流-Dinic(可做模板)(POJ2396)

    //有流量上下界的网络流 //Time:47Ms Memory:1788K #include<iostream> #include<cstring> #include<c ...

  5. SGU 194. Reactor Cooling(无源汇有上下界的网络流)

    时间限制:0.5s 空间限制:6M 题意: 显然就是求一个无源汇有上下界的网络流的可行流的问题 Solution: 没什么好说的,直接判定可行流,输出就好了 code /* 无汇源有上下界的网络流 * ...

  6. 【ZOJ2314】Reactor Cooling(有上下界的网络流)

    前言 话说有上下界的网络流好像全机房就我一个人会手动滑稽,当然这是不可能的 Solution 其实这道题目就是一道板子题,主要讲解一下怎么做无源无汇的上下界最大流: 算法步骤 1.将每条边转换成0~u ...

  7. ZOJ 2314 有上下界的网络流

    problemCode=2314">点击打开链接 题意:给定m条边和n个节点.每条边最少的流量和最多的流量.保证每一个节点的出入流量和相等,问能够形成吗,能够则输出每条边的流量 思路: ...

  8. poj_2396 有上下界的网络流

    题目大意 一个mxn的矩阵,给出矩阵中每一行的和sh[1,2...m]以及每一列的数字的和目sv[1,2...n],以及矩阵中的一些元素的范围限制,比如a[1][2] > 1, a[2][3] ...

  9. 【BZOJ2502】清理雪道 有上下界的网络流 最小流

    [BZOJ2502]清理雪道 Description        滑雪场坐落在FJ省西北部的若干座山上. 从空中鸟瞰,滑雪场可以看作一个有向无环图,每条弧代表一个斜坡(即雪道),弧的方向代表斜坡下降 ...

随机推荐

  1. C语言-if语句

    1.一般形式 if(表达式)表达式1 else 表达式2   :表达式成立(为真)则执行表达式1,否则执行表达式2. 适用范围:真假,对错,开关,对立面的条件 注意:如果if语句中只包括一条语句,可以 ...

  2. APK的反编译

    有秘密的地方就有见不得光的东西,我讨厌这些,所以对于某一个XX圈APP极其反感,感觉就像一个色情网站 一.ApkTool的使用 看了几个教程,自己下载的好像总是不完整,下载包解压后一个没有aapt.e ...

  3. ksoap2- webservice

    1.概述 对于J2ME访问远端的Web Service,除了官方标准JSR 172,我们还有两种选择: l         kSOAP l         Wingfoot Wingfoot是由Win ...

  4. KMP算法深入解析

    本文主要介绍KMP算法原理.KMP算法是一种高效的字符串匹配算法,通过对源串进行一次遍历即可完成对字符串的匹配. 1.基础知识的铺垫 字符串T的前k(0 =< k <=tlen)个连续的字 ...

  5. iOS 之 UITextView

    _lableAssess = [[UITextView alloc] init]; [_lableAssess setFrame:CGRectMake(left2, top2, width2, siz ...

  6. centos 6.5下安装文件上传下载服务

    centos 6.5下安装文件上传下载服务 由于每次在CentOS中要下载一些配置文件到物理机,和上传一些文件到服务器,导致来回的开启ftp软件有点麻烦,这里我们可以使用文件上传下载服务,来解决上传和 ...

  7. CentOS 6.6下JDK1.7安装与配置(Linux)经典入门详解案例

    最近用的linux较多,在网站找了一些关于linux环境下jdk安装的教程,过程是有的但是好多细节都没有表现出来,所以我花了点时间总结了一下,希望对大家都有帮助... CentOS下JDK1.7安装与 ...

  8. Linux 系统分区

    合理的系统分区,便于后期管理和提高文件的搜索速度 分区格式说明 linux分区不同于windows,linux下硬盘设备名为(IDE硬盘为hdx(x为从a—d)因为IDE硬盘最多四 个,SCSI,SA ...

  9. Intent的属性及Intent-filter配置——Data、Type属性与intent-filter配置

    Data属性通常用于向Action属性提供操作的数据,Data属性接受一个Uri对象,一个Uri对象通常通过如下形式的字符串来表示: content://com.android.contacts/co ...

  10. HDU-1430-素数回文

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1431 这题之前做过,又不会做了, 思路先直接暴力,输入a=5 b=500000000得到最大的值为9 ...