POJ 2396 有上下界的可行流
题意:
有一个n*m的方阵,里面的数字未知,但是我们知道如下约束条件:
每一行的数字的和
每一列的数字的和
某些格子有特殊的大小约束,用大于号,小于号和等于号表示
问:是否存在用正数填充这个方阵的方案,满足所有的约束,若有,输出之,否则输出IMPOSSIBLE。
题解:
参考的别人(darksword)的。
总结一下建图,忘了的时候还可以回顾~
求解一个有上下界的网络流的步骤:
1.首先进行构图,对于那么对流量没有限制的边,我们直接将容量赋值为原始的容量,而对于有流量要求的边,我们将容量减去下界并将其等价与无下界的边。最后就是添加一个附
加汇点和一个附加源点,从附加源点连向每个顶点的容量为以该点所有流入的下界流量总和,每个顶点流向附加汇点是该点流出的下界流量总和。
2.我们要添加一条从汇点到源点流量为INF的边,这条边的意义在于,能够使得源点会汇点满足成为流量平衡条件的普通节点。
(以下为有上下界的最小流求解步骤)
3.我们在以附加源点和附加汇点求一次最大流,如果所有的到附加汇点的边都满载,那么说明这个网络是存在满足所有下界的可行流的。因为去除了下界容量的图具备这个能力。但
是此时的可行流(从汇点流向源点的流量)并不一定是最小流,因为满足情况的可行流是不唯一的。
4.紧接着,我们在原图上从汇点向源点求一次最大流(此时要删除掉那条从汇点到源点的INF的边),此时便是一个缩流的过程,旨在试探图中是否还存在流量去替代汇点到源点的流量。这里计算出来的结果可能比我们已得到的可行流还要大,意思是说从汇点到源点有的是空间,因此也就不必连接那条INF的边了,整个网络的流量可以为0,网络中存在环流。
由于这里免不了会进行删边的操作,因此我们直接找到那条边,把流量赋值为0就可以了。
求解有上下界的最小流还有一种二分从汇点到原点的边的容量的方法~
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 有上下界的可行流相关推荐
- BZOJ2406矩阵——有上下界的可行流+二分答案
题目描述 输入 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. 输出 第一行,输出最小的答案: 样例输入 2 2 0 1 2 1 0 1 样例输出 1 ...
- SGU-176 Flow construction 有上下界的最小流
这里参看了大牛的解题思路,学习了很多.原来上下界流的求法是这么的灵活,尤其我是用的临界表存储的边,删除更新很不方便. http://www.shuizilong.com/house/archives/ ...
- CodeForces - 1252L Road Construction(基环树+有源汇有上下界的最大流)
题目链接:点击查看 题目大意:给出 n 个节点,再给出 n 个出边,保证所有的边能将 n 个点连通,每条出边可以用 m[ i ] 种材料选择其一建造,然后有 k 个工人,每个工人只可以使用一种材料建造 ...
- 洛谷 - P5192 Zoj3229 Shoot the Bullet|东方文花帖|【模板】有源汇上下界最大流(有源汇有上下界的最大流)
题目链接:点击查看 题目大意:一共有 n 天,每天可以拍最多 D[ i ] 张照片,每天可以选择 C[ i ] 个少女进行拍照,每个少女的编号为 T[ i ][ j ] ,每个少女需要拍摄照片的区间为 ...
- [bzoj3698]XWW的难题——有上下界的最大流
题目大意: XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核. XWW给你出了这么一个难题:XWW给你一个N*N的正实数矩 ...
- 【bzoj3876】【AHOI2014】【支线剧情】【有上下界的费用流】
Description [故事背景] 宅男JYY非常喜欢玩RPG游戏,比如仙剑,轩辕剑等等.不过JYY喜欢的并不是战斗场景,而是类似电视剧一般的充满恩怨情仇的剧情.这些游戏往往 都有很多的支线剧情,现 ...
- poj 2396 Budget 边容量有上下界的最大流
题意: 给一个矩阵的每行和及每列和,在给一些行列或点的限制条件.求一个满足的矩阵. 分析: 转化为有上下界的网络流,注意等于也是一种上下界关系,然后用dinic算法. 代码: //poj 2396 / ...
- LOJ - #116. 有源汇有上下界最大流(有源汇有上下界的最大流)
题目链接:点击查看 题目大意:给出一个 n 个点和 m 条边的有向图,每条边都有一个流量限制 [ lower , upper ],给定源点 s 和汇点 t ,求出源点到汇点的最大流 题目分析:参考博客 ...
- 【BZOJ3698】XWW的难题 有上下界的最大流
[BZOJ3698]XWW的难题 Description XWW是个影响力很大的人,他有很多的追随者.这些追随者都想要加入XWW教成为XWW的教徒.但是这并不容易,需要通过XWW的考核. XWW给你出 ...
最新文章
- mysql genlog 分析_Mysq性能分析 —— Genral log(普通日志)与 Slow log(慢速日式)...
- SlidingMenu实现侧滑
- 在SQL Server里如何进行页级别的恢复
- 程序员操作系统推荐_为什么程序员要会 Linux
- 盘点 2017 年度最受欢迎的十大 Linux 服务器发行版
- Java web 基础
- QPS、TPS、PV、UV、GMV、IP、RPS?
- 如何在脱敏数据中使用BERT等预训练模型
- 13 个设计 REST API 的最佳实践
- 肌电信号 原始信号 积分_实验室人必看!复杂的色谱峰要如何正确积分?
- 中国证券IT发展简史(上)
- 2020字节跳动数据库面试题及答案
- Android音视频编辑器架构图与分析
- html cat文本,网页管理好管家CatHtml
- 神经网络数据分析案例题,神经网络模型数据处理
- Executing statements
- Contextual Diversity for Active Learning阅读笔记
- Hololens学习(一)安装 部署Hololens开发环境
- 为什么我星际争霸画面是窗口_为什么我喜欢看全球星际联盟
- SSH服务移植到ARM单板