1. 程式人生 > >網路流中求最大流的模板

網路流中求最大流的模板

const int N = 205;
const int inf = 0x3f3f3f3f;
int visit[N], layer[N];
int n, m;// 1代表源點,m代表匯點
int g[N][N];
bool layering() //進行分層
{
    deque<int> q;//雙向佇列
    memset(layer, -1, sizeof(layer));
    q.push_back(1);
    layer[1] = 0;
    while (!q.empty())
    {
        int front = q.front();
        q.pop_front();
        for
(int i = 1; i <= m; i++) { if (layer[i] == -1 && g[front][i] > 0) { layer[i] = layer[front] + 1; if (i == m) return true; else q.push_back(i); } } } return false; } int dinic() { int
maxflow = 0; deque<int> q; while (layering()) { memset(visit, 0, sizeof(visit)); q.push_back(1), visit[1] = 1; while (!q.empty()) { int front = q.back(); if (front == m) //如果該點是匯點 { int minflow = inf, minflow_no;// 最小流以及最小流的起始點
for (int i = 1; i < (int)q.size(); i++) //在雙向佇列裡尋找 { int s = q[i - 1], e = q[i]; if (g[s][e] < minflow) minflow = g[s][e], minflow_no = s; } maxflow += minflow; for (int i = 1; i < (int)q.size(); i++) //新增反向邊 { int s = q[i - 1], e = q[i]; g[s][e] -= minflow, g[e][s] += minflow; } while (!q.empty()&&q.back()!=minflow_no) //回溯到最小流的起始點或棧頂 { visit[q.back()] = 0; q.pop_back(); } } else //如果不是匯點則繼續向下尋找 { int i; for ( i = 1; i <= m; i++) { if (g[front][i] > 0 && layer[i] == layer[front] + 1 && !visit[i]) { visit[i] = 1; q.push_back(i); break; } } if (i > m) //如果沒找到則回溯 { q.pop_back(); } } } } return maxflow; }