题意:

有一个n*m的方阵,里面的数字未知,但是我们知道如下约束条件:

每一行的数字的和

每一列的数字的和

某些格子有特殊的大小约束,用大于号,小于号和等于号表示

问:是否存在用正数填充这个方阵的方案,满足所有的约束,若有,输出之,否则输出IMPOSSIBLE。

题解:

参考的别人(darksword)的。

总结一下建图,忘了的时候还可以回顾~

求解一个有上下界的网络流的步骤:

1.首先进行构图,对于那么对流量没有限制的边,我们直接将容量赋值为原始的容量,而对于有流量要求的边,我们将容量减去下界并将其等价与无下界的边。最后就是添加一个附
加汇点和一个附加源点,从附加源点连向每个顶点的容量为以该点所有流入的下界流量总和,每个顶点流向附加汇点是该点流出的下界流量总和。

2.我们要添加一条从汇点到源点流量为INF的边,这条边的意义在于,能够使得源点会汇点满足成为流量平衡条件的普通节点。

(以下为有上下界的最小流求解步骤)
3.我们在以附加源点和附加汇点求一次最大流,如果所有的到附加汇点的边都满载,那么说明这个网络是存在满足所有下界的可行流的。因为去除了下界容量的图具备这个能力。但
 是此时的可行流(从汇点流向源点的流量)并不一定是最小流,因为满足情况的可行流是不唯一的。

4.紧接着,我们在原图上从汇点向源点求一次最大流(此时要删除掉那条从汇点到源点的INF的边),此时便是一个缩流的过程,旨在试探图中是否还存在流量去替代汇点到源点的流量。这里计算出来的结果可能比我们已得到的可行流还要大,意思是说从汇点到源点有的是空间,因此也就不必连接那条INF的边了,整个网络的流量可以为0,网络中存在环流。

由于这里免不了会进行删边的操作,因此我们直接找到那条边,把流量赋值为0就可以了。

求解有上下界的最小流还有一种二分从汇点到原点的边的容量的方法~

View Code

  1 #include <cstdio>
  2 #include <iostream>
  3 #include <cstring>
  4 #include <cstdlib>
  5
  6 #define N 400
  7 #define INF 1000000000
  8
  9 using namespace std;
 10
 11 int cap[N][N],up[N][N],down[N][N],flow[N][N],in[N],out[N];
 12 int q[N*100],layer[N];
 13 int n,m,T,S,TT,SS,sum,cas;
 14
 15 inline void read()
 16 {
 17     memset(down,0,sizeof down);
 18     memset(flow,0,sizeof flow);
 19     memset(cap,0,sizeof cap);
 20     memset(in,0,sizeof in);
 21     memset(out,0,sizeof out);
 22     memset(up,0,sizeof up);
 23     scanf("%d%d",&n,&m);
 24     for(int i=1;i<=n;i++)
 25         for(int j=1;j<=m;j++)
 26             up[i][j+n]=INF;
 27     S=0; T=n+m+1;
 28     for(int i=1,a;i<=n;i++)
 29     {
 30         scanf("%d",&a);
 31         up[S][i]=down[S][i]=a;
 32     }
 33     for(int i=1,a;i<=m;i++)
 34     {
 35         scanf("%d",&a);
 36         up[i+n][T]=down[i+n][T]=a;
 37     }
 38     int qu; char str[4]; scanf("%d",&qu);
 39     for(int i=1,a,b,c;i<=qu;i++)
 40     {
 41         scanf("%d%d%s%d",&a,&b,str,&c);
 42         if(a==0&&b==0)
 43         {
 44             if(str[0]=='=')
 45             {
 46                 for(int j=1;j<=n;j++)
 47                     for(int k=1;k<=m;k++)
 48                     {
 49                         down[j][k+n]=c;
 50                         up[j][k+n]=c;
 51                     }
 52             }
 53             else if(str[0]=='>')
 54             {
 55                 for(int j=1;j<=n;j++)
 56                     for(int k=1;k<=m;k++)
 57                         down[j][k+n]=max(c+1,down[j][k+n]);
 58             }
 59             else
 60             {
 61                 for(int j=1;j<=n;j++)
 62                     for(int k=1;k<=m;k++)
 63                         up[j][k+n]=min(c-1,up[j][k+n]);
 64             }
 65         }
 66         else if(a==0&&b!=0)
 67         {
 68             if(str[0]=='=')
 69             {
 70                 for(int j=1;j<=n;j++)
 71                 {
 72                     down[j][b+n]=c;
 73                     up[j][b+n]=c;
 74                 }
 75             }
 76             else if(str[0]=='>')
 77             {
 78                 for(int j=1;j<=n;j++)
 79                     down[j][b+n]=max(c+1,down[j][b+n]);
 80             }
 81             else
 82             {
 83                 for(int j=1;j<=n;j++)
 84                     up[j][b+n]=min(c-1,up[j][b+n]);
 85             }
 86         }
 87         else if(b==0&&a!=0)
 88         {
 89             if(str[0]=='=')
 90             {
 91                 for(int j=1;j<=m;j++)
 92                 {
 93                     down[a][j+n]=c;
 94                     up[a][j+n]=c;
 95                 }
 96             }
 97             else if(str[0]=='>')
 98             {
 99                 for(int j=1;j<=m;j++)
100                     down[a][j+n]=max(c+1,down[a][j+n]);
101             }
102             else
103             {
104                 for(int j=1;j<=m;j++)
105                     up[a][j+n]=min(c-1,up[a][j+n]);
106             }
107         }
108         else if(a!=0&&b!=0)
109         {
110             if(str[0]=='=')
111             {
112                 down[a][b+n]=c;
113                 up[a][b+n]=c;
114             }
115             else if(str[0]=='>') down[a][b+n]=max(c+1,down[a][b+n]);
116             else up[a][b+n]=min(c-1,up[a][b+n]);
117         }
118     }
119 }
120
121 inline bool bfs(int st,int ed)
122 {
123     memset(layer,-1,sizeof layer);
124     int h=1,t=2,sta;
125     q[1]=st; layer[st]=0;
126     while(h<t)
127     {
128         sta=q[h++];
129         for(int i=0;i<=ed;i++)
130             if(cap[sta][i]>0&&layer[i]<0)
131             {
132                 layer[i]=layer[sta]+1;
133                 q[t++]=i;
134             }
135     }
136     return layer[ed]!=-1;
137 }
138
139 inline int find(int u,int t,int cur_flow)
140 {
141     if(u==t) return cur_flow;
142     int res=0,tmp;
143     for(int i=0;i<=t&&res<cur_flow;i++)
144         if(cap[u][i]>0&&layer[i]==layer[u]+1)
145         {
146             tmp=find(i,t,min(cur_flow-res,cap[u][i]));
147             cap[u][i]-=tmp; cap[i][u]+=tmp;
148             flow[u][i]+=tmp; flow[i][u]-=tmp;
149             res+=tmp;
150         }
151     if(!res) layer[u]=-1;
152     return res;
153 }
154
155 inline int dinic(int s,int t)
156 {
157     int ans=0;
158     while(bfs(s,t)) ans+=find(s,t,INF);
159     return ans;
160 }
161
162 inline void go()
163 {
164     sum=0;
165     SS=T+1; TT=SS+1;
166     for(int i=0;i<=T;i++)
167         for(int j=0;j<=T;j++)
168         {
169             cap[i][j]=up[i][j]-down[i][j];
170             in[j]+=down[i][j];
171             out[i]+=down[i][j];
172             sum+=down[i][j];
173         }
174     for(int i=0;i<=T;i++)
175     {
176         cap[SS][i]=in[i];
177         cap[i][TT]=out[i];
178     }
179     cap[T][S]=INF;
180     int ans=dinic(SS,TT);
181     if(ans!=sum)
182     {
183         printf("IMPOSSIBLE\n");
184         return;
185     }
186     cap[T][S]=cap[S][T]=0;
187     ans=dinic(S,T);
188     for(int i=1;i<=n;i++)
189     {
190         printf("%d",flow[i][1+n]+down[i][1+n]);
191         for(int j=2;j<=m;j++)
192             printf(" %d",flow[i][j+n]+down[i][j+n]);
193         puts("");
194     }
195     puts("");
196 }
197
198 int main()
199 {
200     scanf("%d",&cas);
201     while(cas--) read(),go();
202     return 0;
203 }

转载于:https://www.cnblogs.com/proverbs/archive/2013/01/05/2846910.html

POJ 2396 有上下界的可行流相关推荐

  1. BZOJ2406矩阵——有上下界的可行流+二分答案

    题目描述 输入 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. 输出 第一行,输出最小的答案: 样例输入 2 2 0 1 2 1 0 1 样例输出 1 ...

  2. SGU-176 Flow construction 有上下界的最小流

    这里参看了大牛的解题思路,学习了很多.原来上下界流的求法是这么的灵活,尤其我是用的临界表存储的边,删除更新很不方便. http://www.shuizilong.com/house/archives/ ...

  3. CodeForces - 1252L Road Construction(基环树+有源汇有上下界的最大流)

    题目链接:点击查看 题目大意:给出 n 个节点,再给出 n 个出边,保证所有的边能将 n 个点连通,每条出边可以用 m[ i ] 种材料选择其一建造,然后有 k 个工人,每个工人只可以使用一种材料建造 ...

  4. 洛谷 - P5192 Zoj3229 Shoot the Bullet|东方文花帖|【模板】有源汇上下界最大流(有源汇有上下界的最大流)

    题目链接:点击查看 题目大意:一共有 n 天,每天可以拍最多 D[ i ] 张照片,每天可以选择 C[ i ] 个少女进行拍照,每个少女的编号为 T[ i ][ j ] ,每个少女需要拍摄照片的区间为 ...

  5. [bzoj3698]XWW的难题——有上下界的最大流

    题目大意: XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核. XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩 ...

  6. 【bzoj3876】【AHOI2014】【支线剧情】【有上下界的费用流】

    Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现 ...

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

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

  8. LOJ - #116. 有源汇有上下界最大流(有源汇有上下界的最大流)

    题目链接:点击查看 题目大意:给出一个 n 个点和 m 条边的有向图,每条边都有一个流量限制 [ lower , upper ],给定源点 s 和汇点 t ,求出源点到汇点的最大流 题目分析:参考博客 ...

  9. 【BZOJ3698】XWW的难题 有上下界的最大流

    [BZOJ3698]XWW的难题 Description XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核. XWW给你出 ...

最新文章

  1. mysql genlog 分析_Mysq性能分析 —— Genral log(普通日志)与 Slow log(慢速日式)...
  2. SlidingMenu实现侧滑
  3. 在SQL Server里如何进行页级别的恢复
  4. 程序员操作系统推荐_为什么程序员要会 Linux
  5. 盘点 2017 年度最受欢迎的十大 Linux 服务器发行版
  6. Java web 基础
  7. QPS、TPS、PV、UV、GMV、IP、RPS?
  8. 如何在脱敏数据中使用BERT等预训练模型
  9. 13 个设计 REST API 的最佳实践
  10. 肌电信号 原始信号 积分_实验室人必看!复杂的色谱峰要如何正确积分?
  11. 中国证券IT发展简史(上)
  12. 2020字节跳动数据库面试题及答案
  13. Android音视频编辑器架构图与分析
  14. html cat文本,网页管理好管家CatHtml
  15. 神经网络数据分析案例题,神经网络模型数据处理
  16. Executing statements
  17. Contextual Diversity for Active Learning阅读笔记
  18. Hololens学习(一)安装 部署Hololens开发环境
  19. 为什么我星际争霸画面是窗口_为什么我喜欢看全球星际联盟
  20. SSH服务移植到ARM单板

热门文章

  1. Android开发笔记(一百六十)休眠模式下的定时器控制
  2. String:字符串常量池
  3. shell脚本通过ping命令来获取平均延时
  4. 【Sofa】Sofa比赛成绩记录
  5. 每天一道博弈论之“巴什博弈”
  6. Thinkpad SL400安装黑苹果10.8.4全纪录
  7. MySQL 执行计划
  8. 计算机VFP输出方式有哪几种,VFP导出数据的方法大全
  9. 【实用工具】之CSDN表格模板
  10. 【调试手段】之valgrind在ARM上的交叉编译