最大流
dinic
- 思路:先bfs找出每个点的深度,然后按照深度进行dfs
bool bfs()
{
memset(dis,-1,sizeof(dis));
memset(vst,0,sizeof(vst));
queue <int> q;
q.push(S);dis[S]=0;vst[S]=1;
while(!q.empty())
{
int a=q.front(),x;q.pop();
if(a==T)return 1;
for(int i=h[a];i;i=g[i].next)
{
x=g[i].to;
if(g[i].v>0&&vst[x]==0)
{
vst[x]=1;dis[x]=dis[a]+1;q.push(x);
}
}
}
return 0;
}
long long dfs(int a,long long maxx)
{
long long res=0,dlt;
int x;
if(a==T||maxx==0)return maxx;
for(int i=h[a];i;i=g[i].next)
{
x=g[i].to;
if(g[i].v<=0||dis[x]!=dis[a]+1)continue;
dlt=dfs(x,min(maxx,g[i].v));
if(dlt==0)dis[x]=0;
g[i].v-=dlt;g[i^1].v+=dlt;
res+=dlt;maxx-=dlt;
if(maxx==0)return res;
}
return res;
}
long long dinic()
{
long long ans=0;
while(bfs())
{
ans+=dfs(S,inf);
}
return ans;
}
sap
- 思路:利用$ d[ ] \(数组记录每个点的当前深度,从深度高的点到深度小1的点dfs,
\) gap[ ] $ 记录每个深度的点的数量,当增加当前点的深度后原深度的点的数量为0时,出现断层,无法继续dfs,标记$ d[T]=ed $然后退出循环
long long dfs(int a,long long maxx)
{
if(a==T||maxx==0)return maxx;
int x,i;
long long dlt,res=0;
for(i=h[a];i;i=g[i].next)
{
x=g[i].to;
if(d[x]!=d[a]-1||g[i].v<=0)continue;
dlt=dfs(x,min(maxx,g[i].v));
g[i].v-=dlt;g[i^1].v+=dlt;
res+=dlt;maxx-=dlt;
if(maxx==0||d[T]==ed)return res;
}
if(--gap[d[a]]==0)d[T]=ed;
d[a]++;gap[d[a]]++;
return res;
}
long long sap()
{
long long ans=0;gap[0]=n;
while(d[T]!=ed)
{
ans+=dfs(S,inf);
}
return ans;
}