E-K
int maxflow()//函数每次返回一个增广路上的最小容量,不断累加这个容量,直到返回值为0即可得到最大流
{
int i;
bool judge=false;
while(!q.empty()) q.pop();//q为普通的队列
memset(vis,0,sizeof(vis));
memset(pre,0,sizeof(pre));//记录前驱
q.push(1);//源点入队
vis[1]=1;
pre[1]=0;
while(!q.empty())
{
int z=q.front();
q.pop();
for(i=1;i<=n;i++)
{
if(g[z][i]>0&&!vis[i])
{
pre[i]=z;
vis[i]=1;
if(i==n)//n为汇点,找到了1条源到汇的路径
{
judge=true;
break;
}
else q.push(i);
}
}
}
if(!judge) return 0;//找不到则返回0
int ret=mmax;
int v;
v=n;
while(pre[v])//找出路径上的最小容量
{
if(g[pre[v]][v]<ret)
ret=g[pre[v]][v];
v=pre[v];
}
v=n;
while(pre[v])//更新路径上的容量,原来的容量要减去最小容量,并增加1条同最小容量的反向边
{
g[pre[v]][v]-=ret;
g[v][pre[v]]+=ret;
v=pre[v];
}
return ret;
}
DINIC
bool countlayer()
{
int i;
memset(layer, -1, sizeof(layer));
deque<int> q;//双端队列,此时表示的是队列
layer[1] = 0;
q.push_back(1);
while(!q.empty())
{
int z = q.front();
q.pop_front();
for(i = 1;i <= n;i++)
{
if(g[z][i] > 0 && layer[i] == -1)
{
layer[i] = layer[z]+1;
if(i == n)//汇点层数能求出,返回真值
return true;
else
q.push_back(i);
}
}
}
return false;
}
int maxflow()
{
deque<int> q;//双端队列,此时表示的是栈
int i, ans = 0;//ans记录最大流
while(countlayer())//只要能分层
{
q.push_back(1);
memset(vis, 0, sizeof(vis));
vis[1] = 1;
while(!q.empty())
{
int z = q.back();
if(z == n)//栈顶元素为汇点
{
int ret = mmax;//记录增广路上的最小流量边
int retu;//最小流量边的起点
for(int i = 1;i < q.size();i++)
{
if(g[q[i-1]][q[i]] > 0 && g[q[i-1]][q[i]] < ret)
{
ret = g[q[i-1]][q[i]];
retu = q[i-1];
}
}
ans += ret;//加入最大流
for(i = 1;i < q.size();i++)//更新流量
{
g[q[i-1]][q[i]] -= ret;
g[q[i]][q[i-1]] += ret;
}
while(!q.empty() && q.back() != retu)//回溯到最小流量边的起点
{
vis[q.back()] = 0;
q.pop_back();
}
}
else
{
for(i = 1;i <= n;i++)
{
if(g[z][i] > 0 && layer[i] == layer[z] + 1 && !vis[i])//必须找下层节点
{
vis[i] = 1;
q.push_back(i);
break;
}
}
if(i > n)
q.pop_back();//找不到就回溯,但不要更新vis
}
}
}
return ans;//返回的即为最大流
}