网络流-Dinic
2015-08-09 00:31
459 查看
http://comzyh.com/blog/archives/568/
http://blog.csdn.net/pi9nc/article/details/23339111
http://wenku.baidu.com/link?url=QcjoxjvmNIGIyvaRRYN5_Jimdj0fI1F3-y1XfjkHBON9c6_eNUbfpDXKRjwGuztLwYvhobWVRDWkEclaq1iu24m2CJVVHH60iQBACHdcTVm
还可以看看我在宁波工程学院集训队PPT的基础上修改的网络流PPT
论文:国家集训队2007论文集里的王欣上《浅谈基于分层思想的网络流算法》也很好。
反向边:从层次图中第 i 层给返回到 i - 1层的路;
增广:从层次图里的第一层到第二层,再继续到汇点,然后根据递归性质返回到增广前原路中源点能到达的最远点,继续从这个点的其他边找路。
层次图:按照【从源点到该点的最短距离】分层的图,如
Dinic算法步骤:
1、根据残存网络计算层次图。若源点不能与汇点联通,则算法结束
2、在层次图中使用DFS进行增广直到不存在增广路
3、转步骤1直至源汇点不通
http://blog.csdn.net/pi9nc/article/details/23339111
http://wenku.baidu.com/link?url=QcjoxjvmNIGIyvaRRYN5_Jimdj0fI1F3-y1XfjkHBON9c6_eNUbfpDXKRjwGuztLwYvhobWVRDWkEclaq1iu24m2CJVVHH60iQBACHdcTVm
还可以看看我在宁波工程学院集训队PPT的基础上修改的网络流PPT
论文:国家集训队2007论文集里的王欣上《浅谈基于分层思想的网络流算法》也很好。
反向边:从层次图中第 i 层给返回到 i - 1层的路;
增广:从层次图里的第一层到第二层,再继续到汇点,然后根据递归性质返回到增广前原路中源点能到达的最远点,继续从这个点的其他边找路。
层次图:按照【从源点到该点的最短距离】分层的图,如
Dinic算法步骤:
1、根据残存网络计算层次图。若源点不能与汇点联通,则算法结束
2、在层次图中使用DFS进行增广直到不存在增广路
3、转步骤1直至源汇点不通
#include <string.h> #include <iostream> #include <cstdio> using namespace std; #define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i ) #define CLR( a , x ) memset ( a , x , sizeof (a) ); #define RE freopen("1.in","r",stdin); #define WE freopen("output.txt","w",stdout); #define debug(x) cout<<#x<<":"<<(x)<<endl; const int maxn=205; int tab[maxn][maxn],dis[maxn],n,m; //tab为流量,dis为层次 //bfs找层次图 int bfs(int s,int t) { int q[maxn],head=0,tail=0; q[tail++]=s; memset(dis,-1,sizeof(dis)); dis[s]=0; while(head<tail) { int cur=q[head++]; for(int i=1;i<=n;i++) { if(dis[i]<0&&tab[cur][i]>0) { dis[i]=dis[cur]+1; q[tail++]=i; } } } if(dis[t]>0) return 1; return 0; //dis[t]=-1:路不通 } //dfs为一次增广,s->t int dfs(int s,int t,int low)//Low为增广路径上的最小流量 { int flow=0; if(s==t) return low; //到汇点直接返回目前为止的最小流量 for(int i=1;i<=n;i++) { //在下一层里找 if(tab[s][i]>0 &&dis[i]==dis[s]+1 &&(flow=dfs(i,t,min(low,tab[s][i])))) { tab[s][i]-=flow; //不断的减流量 tab[i][s]+=flow; return flow; //能到汇点 } } return 0; } int main() { // RE int a,b,c; while(cin>>m>>n) { CLR(tab,0); //流量初始化为0 while(m--) { cin>>a>>b>>c; tab[a][b]+=c; //重边 } int ans=0,tans=0; while(bfs(1,n)) //直到源点不能到汇点为止 while(tans=dfs(1,n,0x7FFFFFFF)) //在同一个层次图里尽量找增广路 ans+=tans; cout<<ans<<endl; } return 0; }
相关文章推荐
- 黑马程序员--java基础--网络编程
- tcpreplay工具安装使用
- Java使用HttpURLConnection上传文件
- HttpClient使用详解(http伪造文件上传请求)
- iOS开发网络篇—NSURLConnection基本使用(二)
- 模拟HTTP请求的一个工具
- TCP学习(2)--TCP连接的建立(三次握手)
- TCP和Http的区别
- 理解IP地址和端口号
- 自己封装的XMLHttpRequest2 ajax
- android的Http协议学习与应用——连接一个网页
- http头中的host字段详解
- Http请求头和响应头
- muduo::Acceptor、TcpServer分析
- 常见的HTTP状态码(HTTP Status Code)说明
- Android从网络某个地址下载文件、写入SD卡
- iOS 用GCD下载网络图片方法
- UVa 563 Crimewave (网络流构图+最大流+挺好的+双向边)
- 五层网络体系结构
- HDU 4940 Destroy Transportation system(上下界网络流)