網絡流學習筆記

網絡流學習筆記

第一天: 實現最基礎網絡流算法

基本思路

代碼實現

#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算法的標記方式,保證不由於環而死循環
相關文章
相關標籤/搜索