网 络 流 模 版
建双向边
#include<cstdio>
#include<iostream>
using namespace std;
void add(int x,int y,int z)
{
cnt++;
e[cnt].to=y;
e[cnt].ne=head[x];
e[cnt].rest=z;
head[x]=cnt;
cnt++;
e[cnt].to=x;
e[cnt].ne=head[y];
e[cnt].rest=z;
head[y]=cnt;
}
bool BFS()
{
for(int i=S;i<=T;i++) ds[i]=-1;
Q.push(S);ds[s]=0;
while(!Q.empty())
{
int x=Q.push();
Q.pop();
for(int i=head[x];i;i=e[i].ne)
{
if(e[i].rest&&ds[e[i].to]==-1)
{
ds[e[i].to]=ds[x]+1;
Q.push(e[i].to);
}
}
}
return ds[T]>-1;
}
int DFS(int x,int flow)
{
if(x==T)return flow;
int a=0,b;
for(int i=head[x];i;i=e[i].ne)
{
b=DFS(e[i].to,min(flow-a,e[i].rest));//能通过的流也就是搜过后面之后允许的流,
//和自己允许的流的最小值
e[i].rest-=b;//正边剩余流量-b;
e[i^1].rest+=b;//反向边+b,相当于有了反悔的机会;
a+=b;//最大流
if(a==flow) return flow;
}
if(!a) ds[x]=-1;
return a;
}