zoukankan      html  css  js  c++  java
  • 最大流之sap算法

    若有向图G = (V , E)满足下列条件:

    1、有且仅有一个顶点S,它的入度为 0 ,这个顶点称为源点。

    2、有且仅有一个顶点T,它的出度为 0 ,这个顶点称为汇点。

    3、每一条弧都有一个非负数,叫做这条边的容量,边(Vi , Vj)的容量用 Cij 来表示。

    则此有向图称为网络流图,记为 G = ( V , E , C) ;

    对于网络流图G中,每一条弧( i , j )都给定一个非负数Fij,对于一组数据满足下面三个条件时,称为可行流;

    1、对于每条弧都有 Fij < Cij ;

    2、出了源点S和汇点T之外,中间任意点流量守恒,即输入流等于输出流;

    3、对于源点S和汇点T,从S出去多少就会从T流入多少;

    假如有这么一条路,从源点开始,一直一段一段的连到了汇点,并且这条路上的每一段满足Fij < Cij ,则称这条路为增广路;

    当找不到增广路时,当前流量就是最大流。

    寻找增广路时可以简单地从源点开始做bfs,并不断修改这条路上的最大流。

    但事实上并不是这么简单,上面所说的增广路还不是很完整,中间还存在一些细节问题,例如:

    我们通过bfs遍历后得到第一条增广路 1 - 2 - 3 - 4 ,然后就不存在增广路径了,其实并不是这样,这个网络流的最大流明显为 2 ,我们可以是使用一个叫反向边的概念来解决这个问题,如图:

    这样就解决了增广路算法中的一些细节问题;

    加入一个网络图中有4个点,5条边组成。如下:

    5 4

    1 2 40

    1 4 20

    2 4 20

    2 3 30

    3 4 10

    求最大流是多少?

    下面给出相应的代码:

    #include<iostream>
    #include<queue>
    
    using namespace std ;
    
    int n , m ;
    
    int map[210][210] ;
    
    int path[210] ;
    
    int flow[210] ;
    
    
    int bfs()	{
    	queue<int> q ;
    	memset(path,-1,sizeof(path)) ;
    	path[1] = 0 ;
    	flow[1] = (1<<30) ;
    	q.push(1) ;
    	while(!q.empty())	{
    		int t = q.front() ;
    		q.pop() ;
    		if(t == m) break ;
    		for(int i = 2 ; i <= m ; i++)
    			if(path[i] == -1 && map[t][i])	{      // 该路径没有被访问过
    				flow[i]=flow[t]<map[t][i]?flow[t]:map[t][i];   // 该路径最小流量
    				q.push(i) ;
    				path[i] = t ;	// 存储路径
    			}
    	}
    	if(path[m] == -1) 
    		return -1 ;
    	return flow[m] ;
    }
    
    
    void Edmonds_Karp()	{
    	int max_flow = 0 , floww ;
    	 while((floww=bfs())!=-1)	{
    		max_flow += floww ;
    		int s , t ;
    		t = m ;
    		while(t != 1 )	{
    			s = path[t] ;
    			map[s][t] -= floww ;
    			map[t][s] += floww ;
    			t = s ;
    		}
    	}
    	cout << max_flow << endl ;
    }
    
    
    
    int main()	{
    	while(cin >> n >> m)	{
    		memset(map,0,sizeof(map)) ;
    		while(n--) {
    			int u , v , cost ;
    			cin >> u >> v >> cost ;
    			map[u][v] += cost ;
    		}
    		Edmonds_Karp() ;
    	}
    	return 0 ;
    }
    

      

  • 相关阅读:
    hdoj2187:悼念512汶川大地震遇难同胞 (贪心)
    2.0其它之Transform详解,以及UIElement和FrameworkElement的常用属性
    2.0外观之样式, 模板, 视觉状态和视觉状态管理器
    2.0图形之Ellipse, Line, Path, Polygon, Polyline, Rectangle
    2.0控件之ListBox, MediaElement, MultiScaleImage, PasswordBox, ProgressBar, RadioButton
    2.0画笔之SolidColorBrush, ImageBrush, VideoBrush, LinearGradientBrush, RadialGradientBrush
    2.0图形之基类System.Windows.Shapes.Shape
    2.0交互之鼠标事件和键盘事件
    2.0控件之ScrollViewer, Slider, StackPanel, TabControl, TextBlock, TextBox, ToggleButton
    2.0交互之InkPresenter(涂鸦板)
  • 原文地址:https://www.cnblogs.com/NYNU-ACM/p/4237422.html
Copyright © 2011-2022 走看看