網路流中求最大流的模板
阿新 • • 發佈:2019-02-10
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;
}