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 ;
    }
    

      

  • 相关阅读:
    六.(二)oc分类-category(范畴、非正式协议)
    十二 .ocBlock
    十.oc内存管理
    七.(一)oc通知-NSNotification(通知中心-NSNotificationCenter)
    Storyboard中segue(转场)使用
    XCode 7.3.1(dmg) 官方直接下载地址
    jquery 判定checkbox是否选中
    SqlService 并发测试
    SQL Server 消息队列,处理程序错误
    DB开启 Service Broker,使用消息队列
  • 原文地址:https://www.cnblogs.com/scottding/p/3702277.html
Copyright © 2011-2022 走看看