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

    基本的知识,解决什么问题这些东西就不说啦。算法导论和很多大神博客都讲解的很详细。

    它其实就是不停的找增广路直到找不到为止。此时通过的所有流量就是最大流量。

    我推荐一篇文章:(基本过程讲解的很详细,我很收益。)

    Ford-Fulkerson 最大流算法

    下面是我的实现。

    参考了 最大流Ford-Fulkerson的算法实现

    #include<iostream>
    #include<queue>
    using namespace std;
    #define MAX 1024
    int nodes,edges;
    
    int capacity[MAX][MAX];//记录边的当前还可以通过的最大流量
    int maxflow=0;
    bool isVisited[MAX];//在BFS或DFS找增广路的时候记录该元素是否访问过
    int pre[MAX];//记录节点的前一个节点
    
    /*
    	我最疑惑的地方是capacity[i][pre[i]]+=increase;这个地方。
    	我们一开始以为这只是一个简单的有向图,其实不是,这个有向图会根据它的两个节点之间的通过的流量自动改变
    		我们可以把它看成是最原始的有向图中有箭头的两个节点可以相互通过流,而不仅仅是沿箭头的方向通过流(通过判断两个节点之间的最大
    		流量来判断。)
    
    	表达能力实在有限。。我自己都觉得没说清楚..
    */
    inline int min(int a,int b)
    {
    	return a>b?b:a;
    }
    
    bool DFS(int src)
    {
    	if(!src)
    		pre[src]=-1;
    	if(src==nodes-1)
    		return true;
    	isVisited[src]=true;
    	for(int i=0;i<nodes;i++)
    	{
    		if(!isVisited[i]&&capacity[src][i])
    		{
    			isVisited[i]=true;
    			pre[i]=src;
    			if(DFS(i))
    				return true;
    		}
    	}
    	return false;
    }
    
    bool BFS()
    {
    	queue<int> myQueue;
    	myQueue.push(0);
    	isVisited[0]=true;
    	pre[0]=-1;
    	while(!myQueue.empty())
    	{
    		int current=myQueue.front();
    		myQueue.pop();
    		for(int i=0;i<nodes;i++)
    		{
    			if(!isVisited[i]&&capacity[current][i])
    			{
    				myQueue.push(i);
    				pre[i]=current;
    				isVisited[i]=true;
    			}
    		}
    	}
    	
    	return isVisited[nodes-1];
    }
    
    void MaxFlow()
    {
    	while(1)
    	{
    		memset(isVisited,false,nodes);
    		memset(pre,0xff,4*nodes);
    		
    	//	if(!DFS(0))
    	//		break;
    		if(!BFS())
    			break;
    		
    		int increase=MAX;
    		int i;
    		for(i=nodes-1;pre[i]>=0;i=pre[i])
    		{	
    			increase=min(increase,capacity[pre[i]][i]);
    		}
    		for(i=nodes-1;pre[i]>=0;i=pre[i])
    		{	
    			capacity[pre[i]][i]-=increase;
    			capacity[i][pre[i]]+=increase;
    		}
    		maxflow+=increase;
    		
    
    	}
    }
    void main()
    {
    	while(1)
    	{
    		cin>>nodes>>edges;
    		int firstnode,secondenode,capa;
    		for(int i=0;i<edges;i++)
    		{
    			cin>>firstnode>>secondenode>>capa;
    			capacity[firstnode][secondenode]=capa;
    		}
    		MaxFlow();
    		cout<<maxflow<<endl;
    		maxflow=0;
    
    	}
    	
    }


    这里提供两种找增广路的算法:DFS和BFS。


  • 相关阅读:
    CentOS 7.4 安装python3及虚拟环境
    【抓包工具之Fiddler】增加IP列;session高亮
    【抓包工具之Fiddler】导出jmeter脚本
    Python2.7 Centos安装
    Centos 轻松升级 GCC 不改变系统环境
    GraphLab 安装 出错 "Cannot uninstall 'boto'" "Cannot uninstall 'certifi'"
    Centos6 使用 gbdt lightgbm "libc.so.6: version `GLIBC_2.14' not found" "Segment Fault"
    Linux 安装 gbdt xgboost lightgbm
    Sudo Permission Denied
    Linux Load Average高但磁盘IO和CPU占用率不高的可能原因
  • 原文地址:https://www.cnblogs.com/suncoolcat/p/3402481.html
Copyright © 2011-2022 走看看