zoukankan      html  css  js  c++  java
  • 洛谷 P3376 【【模板】网络最大流】

    来篇EK算法的题解。


    这里用的是邻接表,跑的快一点,因为可以压缩一下重边。

    EK算法的本质就是不断的寻找增广路,然后把找到的所有增广路的流量累加起来。详细的可以看一下洛咕日报的这篇博客

    一些细节会在代码里面指出。

    代码:

    #include <bits/stdc++.h>
    using namespace std;
    long long n , m , s , t , ans;
    long long pre[200010] , dis[2010][2010] , vis[200010] , minn[200010];
    vector<int> e[200010];
    bool bfs(){
    	memset(vis , 0 , sizeof(vis));
    	queue<int> q;
    	vis[s] = 1;
    	q.push(s);
    	minn[s] = 0x3ffffff;
    	while(!q.empty()){
    		int x = q.front();
    		q.pop();
    		for(int i = 0; i < e[x].size(); i++){
    			int nx = e[x][i];
    			if(dis[x][nx] > 0){
    				if(vis[nx]) continue;
    				minn[nx] = min(minn[x] , dis[x][nx]);	//找出最小容量 
    				pre[nx] = x;	//记录前驱 
    				q.push(nx);
    				vis[nx] = 1;
    				if(nx == t) return 1;
    			}
    		}
    	}
    	return 0;
    }
    void update(){	//更新剩余容量 
    	int x = t;
    	while(x != s){
    		int px = pre[x];
    		dis[x][px] += minn[t];
    		dis[px][x] -= minn[t];
    		x = px;
    	}
    	ans += minn[t]; 
    }
    int main(){
    	cin >> n >> m >> s >> t;
    	for(int i = 1; i <= m; i++){
    		int x , y , z;
    		cin >> x >> y >> z;
    		e[x].push_back(y);
    		dis[x][y] += z;	//有可能会有重边,需要把容量累加起来,如果直接重新建一条边的话,会因为边太多超时 这个地方的+=我查了几个小时/kk 
    		e[y].push_back(x);	//反向边 
    	}
    	while(bfs()) update();
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    关于http头
    关于js中的命名
    PHP之APC缓存详细介绍
    找回Windows Vista桌面的IE7.0图标
    查看操作系统是不是中文正式版?
    如何判断XP是否已激活
    Vista取消默认共享
    今天是儿童节,祝福儿子节日快乐!
    天天锻炼身体好!
    如何查看你的XP SP2是否原版?
  • 原文地址:https://www.cnblogs.com/bzzs/p/13274380.html
Copyright © 2011-2022 走看看