【网络流#5】UVA 11082 最大流

摘要:
首先,计算第i行r[i]中元素的和和第j列c[j]中元素元素的和,然后构建一个图。每行转换为节点1~n,每列转换为节点n+1~n+m源点到1~n,分别连接容量为r[i]-mn+1~n+m的边缘到汇点,分别连接一个容量为c[i]-n1~n到n+1~n+m的边,运行网络流1#include<csdio>2#include˂cstring>3#include˂cmath>4#include<iostream>5#include˂algorithm>6#include˂set>7#include«map>8#include˂1 stack>9#include˂5 vector>10#include˂2 queue>11#include≤string>12#include˂/sstream>13#defineMAXN100014#defineMAX M200015#defineINF16#defineeps0.00000117#defineALLx。begin(),x end()18#定义INSinserter19使用namespacestd;20组成f=0x3f3f3f;21inti,j,k,n,m,x,y,T,num,w,cas,s,T,最大流量,u;22structedgenode23{24intfrom,to,next;25intcap;26}edge[MAXM];27intEdge,头部[MAXN],ps[MAXN]dep[MAXN',r[MAXN],c[MAXN},tt;28英寸[MAXN][MAXN];2930voidadd_Edge31{32edge[Edge].from=x;33edge[Edge].to=y;34edge[Eedge].cap=c;35edge[EEdge].next=head[x];36head[x]=Edge++;3738edge[Ege].from=y;39edge[Eng].to=x;40edge[End].cap=0;41edge[Eidge].next=head[y];42head[y]=Edge++;43}44/*关于此模板:45Edge是前向星形的边数,因此您需要初始化Edge,头阵列46n指示有n个点。在这个版本中,点是从0开始还是从1开始并不重要。S表示源点,t表示宿47。一个好消息是,这个版本的DFS使用模拟堆栈来防止堆栈爆炸48*/4950 intdinic51{52 inttr,res=0;53 int i,j,k,l,r,top;54而{55 memset;56表示(l=dep[ps[0]=S〕=0,r=1;l!

网络流题目最有意思的地方就是构图了,毕竟套模板每个人都会的

现在有一个矩阵,已知前i行元素之和a[i](1<=i<=n),前j列元素之和b[j](1<=j<=m),求一个可行的矩阵,且矩阵每个元素在区间[1,20]内。

这也算是含上下界的网络流了,但是显然,如果将每个元素都减一,就是普通的最大流了,矩阵元素值在区间[0,19]内。

首先求出第i行元素之和r[i],第j列元素之和c[j],

然后就是建图,每行化为一个结点1~n,每列化为一个结点n+1~n+m

源点到1~n,分别连一条边,容量为r[i]-m

n+1~n+m到汇点,分别连一条边,容量为c[i]-n

1~n到n+1~n+m,分别连一条容量为19的边

这样跑一发网络流

【网络流#5】UVA 11082 最大流第1张【网络流#5】UVA 11082 最大流第2张
  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cmath>
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<set>
  7 #include<map>
  8 #include<stack>
  9 #include<vector>
 10 #include<queue>
 11 #include<string>
 12 #include<sstream>
 13 #define MAXN 1000
 14 #define MAXM 2000
 15 #define INF (1<<30)
 16 #define eps 0.000001
 17 #define ALL(x) x.begin(),x.end()
 18 #define INS(x) inserter(x,x.begin())
 19 using namespace std;
 20 const int inf = 0x3f3f3f3f;
 21 int i,j,k,n,m,x,y,T,num,w,cas,s,t,maxflow,u;
 22 struct edgenode
 23 {
 24     int from,to,next;
 25     int cap;
 26 }edge[MAXM];
 27 int Edge,head[MAXN],ps[MAXN],dep[MAXN],r[MAXN],c[MAXN],tt;
 28 int ans[MAXN][MAXN];
 29 
 30 void add_edge(int x,int y,int c)
 31 {
 32     edge[Edge].from=x;
 33     edge[Edge].to=y;
 34     edge[Edge].cap=c;
 35     edge[Edge].next=head[x];
 36     head[x]=Edge++;
 37     
 38     edge[Edge].from=y;
 39     edge[Edge].to=x;
 40     edge[Edge].cap=0;
 41     edge[Edge].next=head[y];
 42     head[y]=Edge++;
 43 }
 44 /*关于这个模板:
 45 Edge为前向星的边数,所以需要初始化Edge和head数组 
 46 n表示有n个点,这个版无所谓点从0开始还是从1开始,s表示源点,t表示汇点
 47 很好的一个是,这个版的DFS使用的是模拟栈,防止爆栈 
 48 */ 
 49 
 50 int dinic(int n,int s,int t)
 51 {
 52     int tr,res=0;
 53     int i,j,k,l,r,top;
 54     while(1){
 55         memset(dep,-1,(n+1)*sizeof(int));
 56         for(l=dep[ps[0]=s]=0,r=1;l!=r;)//BFS部分,将给定图分层 
 57         {
 58             for(i=ps[l++],j=head[i];j!=-1;j=edge[j].next)
 59             {
 60                 if (edge[j].cap&&-1==dep[k=edge[j].to])
 61                 {
 62                     dep[k]=dep[i]+1;ps[r++]=k;
 63                     if(k==t)
 64                     {
 65                         l=r;
 66                         break;
 67                     }
 68                 }
 69             }
 70         }
 71         if(dep[t]==-1)break;
 72         
 73         for(i=s,top=0;;)//DFS部分 
 74         {
 75             if(i==t)//当前点就是汇点时 
 76             {
 77                 for(k=0,tr=inf;k<top;++k)
 78                     if(edge[ps[k]].cap<tr)tr=edge[ps[l=k]].cap;
 79                     
 80                 for(k=0;k<top;++k)
 81                     edge[ps[k]].cap-=tr,edge[ps[k]^1].cap+=tr;
 82                     
 83                 res+=tr;
 84                 i=edge[ps[top=l]].from;
 85             }
 86             
 87             for(j=head[i];j!=-1;j=edge[j].next)//找当前点所指向的点 
 88                 if(edge[j].cap&&dep[i]+1==dep[edge[j].to]) break;
 89                 
 90             if(j!=-1)
 91             {
 92                 ps[top++]=j;//当前点有所指向的点,把这个点加入栈中 
 93                 i=edge[j].to;
 94             }
 95             else
 96             { 
 97                 if (!top) break;//当前点没有指向的点,回溯 
 98                 dep[i]=-1;
 99                 i=edge[ps[--top]].from;
100             }
101         }
102     }
103     return res;
104 }
105 
106 int main()
107 {
108     scanf("%d",&T);
109     for (cas=1;cas<=T;cas++)
110     {   
111         memset(head,-1,sizeof(head));
112         Edge=0;
113         
114         scanf("%d%d",&n,&m);
115         int pre=0;
116         for (i=1;i<=n;i++)
117         {
118             scanf("%d",&r[i]);
119             add_edge(0,i,r[i]-m-pre);
120             pre=r[i];
121         }
122         tt=n+m+1; 
123         pre=0;
124         for (i=1;i<=m;i++)
125         {
126             scanf("%d",&c[i]);
127             add_edge(i+n,tt,c[i]-n-pre);
128             pre=c[i];
129         }
130         for (i=1;i<=n;i++)
131         {
132             for (j=1;j<=m;j++)
133             {
134                 add_edge(i,n+j,19);
135             }
136         }
137         
138         maxflow=dinic(tt+1,0,tt);
139         //cout<<maxflow<<endl;
140         for (i=1;i<=n;i++)
141         {
142             for (j=head[i];j!=-1;j=edge[j].next)
143             {
144                 u=edge[j].to;
145                 if (u<=n||u>n+m) continue;
146                 ans[i][u-n]=19-edge[j].cap;
147             }
148         }
149         printf("Matrix %d
",cas);
150         for (i=1;i<=n;i++)
151         {
152             for (j=1;j<m;j++)
153             {
154                 printf("%d ",ans[i][j]+1);
155             }
156             printf("%d
",ans[i][m]+1);
157         }
158         if (cas!=T) printf("
");
159     }
160     return 0;
161 }
View Code

免责声明:文章转载自《【网络流#5】UVA 11082 最大流》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇再探NSStringC#_switch语句,for循环,do while循环,while循环下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

网络流(一)基础知识篇

传送门: 网络流(一)基础知识篇 网络流(二)最大流的增广路算法 网络流(三)最大流最小割定理 网络流(四)dinic算法 网络流(五)有上下限的最大流 网络流(六)最小费用最大流问题  转载自:https://blog.csdn.net/txl199106/article/details/64441994 网络流入门 基本概念(从书上摘抄,可以直接...

RTMP流媒体播放过程(转)

http://blog.csdn.net/leixiaohua1020/article/details/11704355 本文描述了从打开一个RTMP流媒体到视音频数据开始播放的全过程。 注意:RTMP中的逻辑结构 RTMP协议规定,播放一个流媒体有两个前提步骤:第一步,建立一个网络连接(NetConnection);第二步,建立一个网络流 (NetStr...

RTMP流媒体播放过程(转)

本文描述了从打开一个RTMP流媒体到视音频数据开始播放的全过程。 注意:RTMP中的逻辑结构 RTMP协议规定,播放一个流媒体有两个前提步骤:第一步,建立一个网络连接(NetConnection);第二步,建立一个网络流(NetStream)。其中,网络连接代表服务器端应用程序和客户端之间基础的连通关系。网络流代表了发送多媒体数据的通道。服务器和客户端之间...

bzoj网络流

近期看了一些bzoj的网络流,深感智商不够。不过对于网络流又有了进一步的理解。 还是mark一下吧。 献上几篇论文:1)《最小割模型在信息学竞赛中的应用》                     2)《浅析一类最小割问题》 1、bzoj1066(最大流) 题意:戳这里 思路:很明显拆点最大流模型,然后对于每个点每个高度流量限为1,那么根据最大流即为可以出去...

cogs 14. [网络流24题] 搭配飞行员

14. [网络流24题] 搭配飞行员★★☆ 输入文件:flyer.in 输出文件:flyer.out简单对比时间限制:1 s 内存限制:128 MB 【问题描述】 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员。由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾...

网络流(二)——最大流最小割定理

最小割<1>什么是割?引例:你的仇人是一个工厂老板.你要炸掉一些车,让他每个货物都运不到销售点.炸掉越大的车,你越容易被发现.你希望炸掉的车的容量之和尽量小.最小化这个值.定义:选出一些边的集合,使得删除它们之后从源点无法到达汇点,那么这个集合就叫做一个割.这些边的容量之和称作这个割的容量.<2>最小割最大流定理定理1:任取一个割,...