网络流中求最大流的模板

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;
}

猜你喜欢

转载自blog.csdn.net/jinduo16/article/details/81707589