zoukankan      html  css  js  c++  java
  • 网络流学习笔记

    网络流学习笔记

    第一天: 实现最基础网络流算法

    基本思路

    代码实现

    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <memory.h> 
    using namespace std;
    const int MAXN = 100;
    const int MAXM = MAXN*MAXN;
    const int INF = 0x3f3f3f3f;
    int head[MAXN], Next[MAXM], ver[MAXM], edge[MAXM], flow[MAXM];
    int tot;
    
    void init(){
    	tot = 0;
    	memset(head, 0, sizeof(head));
    }
    void add(int x, int y, int z, int f){
    	Next[++tot] = head[x];
    	head[x] = tot;
    	ver[tot] = y;
    	edge[tot] = z;
    	flow[tot] = f;
    }
    
    void add2(int x, int y, int z){
    	add(x, y, z, 0);
    	add(y, x, z, z);
    }
    int ss, tt, res[MAXN], pre[MAXN], v[MAXN], pre_index;
    int bfs(){
    	int x = ss;
    	queue <int> q;
    	while(!q.empty()) q.pop();
    	memset(pre, 0, sizeof(pre));
    	memset(res, 0, sizeof(res));
    	memset(v, 0, sizeof(v));
    	pre_index = 0;
    	res[x] = INF;
    
    	q.push(x);
    	v[x] = 1;
    	int c = 0;
    	while(!q.empty()){
    		x = q.front(); q.pop();
    		for(int i = head[x]; i; i = Next[i]){
    			int y = ver[i], z = edge[i], f = flow[i];
    			
    			//cout << y <<"flow"<<f<<endl;
    			int fr = z-f;
    			//可流判断
    			if(fr > 0){
    				if(v[y]) continue;
    				c++;
    				cout << c << x << "->" << y << ":" << fr << endl; 
    				int t = min(res[x], fr);
    				res[x]-=t;
    				res[y]+=t;
    				q.push(y);
    				v[y] = 1;
    				pre[pre_index++] = i;
    				if(y == tt){
    					return t;
    				}
    			}
    		}
    	}
    	return 0;
    }
    
    
    int EK(){
    	int f = 0, ans = 0;
    	while(1){
    		cout << f << endl;
    		for(int i = 0; i < pre_index; i++){
    			//cout << "iii" << pre[i] << endl;
    			flow[pre[i]] += f;
    			flow[pre[i]%2?pre[i]-1:pre[i]+1] -= f;
    		}
    		ans+=f;
    		f = bfs();
    		if(f == 0) break;
    	}
    	return ans;
    }
    int main(){
    	//输入n点m边
    	//节点编号从1开始
    	int n, m;
    	cin >> n >> m;
    	cin >> ss >> tt;
    	init();
    	for(int i = 1; i <= m; i++){
    		int a, b, z, f;
    		cin >> a >> b >> z;
    		add2(a, b, z);
    	}
    	cout << EK() << endl;
    }
    /*
    6 8
    1 4
    1 6 2
    6 5 1
    5 4 3
    3 4 2
    1 4 3
    2 3 1
    1 2 2
    1 3 2
    */ 
    
    

    遇到问题

    死循环
    1. 邻接表的终止值是0还是-1需要考虑清楚
    bfs搜索错误
    1. 由于可能出现环,需要标记进入队列的点,借用spaf算法的标记方式,保证不因为环而死循环
  • 相关阅读:
    凹透镜
    三角形动点和将军饮马
    数学
    壮壮学习准则
    均值不等式,求极值
    2020年自贡中考数学真题,用的是花钱买的"几何画板",wechat:QZCS12
    90年高考题
    裂项:2005年初中数学竞赛题p32,4
    02-需求来源
    01-产品需求的内涵
  • 原文地址:https://www.cnblogs.com/Phoenix-blog/p/10627811.html
Copyright © 2011-2022 走看看