最大流问题预流推进算法(最基本)

/*
  Name: 最大流问题预流推进算法
  Copyright: 
  Author: 巧若拙 
  Date: 14-06-17 09:26
  Description: 最基本的预流推进算法,没有任何优化,每次遍历所有的结点,找出活结点,
  寻找可行弧,并预流推进,若没有可以push的顶点,执行relabel操作。 
*/
#include    
#include   
    
using namespace std;    
    
const int MAXV=2000;   //最大顶点数量     
const int MAXE=2000;   //最大边数量    
const int INFINITY = 0x7fffffff;   //无穷大     
int capacity[MAXV][MAXV]; //记录残流网络的容量    
int flow[MAXV];  //标记当前节点的剩余流量      
int dis[MAXV]; //标记节点所在的层次    

int counts = 0;
    
int MaxFlow_push_relabel(int src, int des, int n) ;   
    
int main()    
{   
    int  m, n, u, v;    
    ifstream fcin("maxflow.txt");  
      
    if (!fcin.is_open())  
    {  
        cout << "Error opening file"; exit (1);  
    }  
    
    fcin >> n >> m;  
     
    for(int i=0; i> u >> v;    
        fcin >> capacity[u][v];        
    }    
      
    cout << n << " " << m << endl;  
    for (int i=0; i 0) //更新结点剩余流量和残流网络 
        {  
            flow[src] -= capacity[src][v];  
            flow[v] = capacity[src][v];  
            capacity[v][src] = capacity[src][v];  
            capacity[src][v] = 0; 
        }  
    }   
    
    while (1)
    {
        done = true;  
        for (u=0; u 0) //寻找活结点 
            {
                done = false;  
                relabel = true;   //先假设顶点u需要relabel  
                for (v=0; v 0) //寻找可行弧,并预流推进 
                    {
                        relabel = false;  
                        minFlow = (flow[u] < capacity[u][v]) ? flow[u] : capacity[u][v];	   
                        flow[u] -= minFlow;  
                        flow[v] += minFlow;  
                        capacity[u][v] -= minFlow;  
                        capacity[v][u] += minFlow; 
                        printf("push %d --%d--> %d, e[%d] = %d\n", u, minFlow, v, u, flow[u]);  
                        if (flow[u] == 0) //无剩余流量了就停止搜索可行弧 
                        {
                            break;
                        }
                    }
                }
                //没有可以push的顶点,执行relabel 
                if (relabel) 
                {   
                    minLevel = INFINITY; 
                    for (v=0; v 0 && minLevel > dis[v]) //寻找下一层节点的最小层高 
                        {
                            minLevel = dis[v];
                        } 
                    }
                    dis[u] = minLevel + 1;
                    printf("relabel %d height to %d\n", u, dis[u]); 
                }  
            }
        }
        if (done) //已经没有活结点了,操作结束 
        { 
            return flow[des];    
        }  
    } 
}    

你可能感兴趣的:(常用算法分析,算法进化历程,图论)