最大流(Dinic)
算法思想
1.bfs()从起始节点开始找到点的深度,以离s起点最近为标准;
2.dfs()找流量正向减去多少,反向加上多少;
例题
洛谷P3376
*
代码
#include <bits/stdc++.h> //代码实现;
using namespace std;
const int N=1e5+55;
const int inf=0x3f3f3f3f;
int deep[N],head[N<<1];
int cnt=2,s,t;
struct node{
int to,next,flow;
}mp[N<<1];
inline void add(int x, int y, int val)
{
mp[cnt].to=y;
mp[cnt].flow=val;
mp[cnt].next=head[x];
head[x]=cnt++;
}
int bfs()
{
memset(deep,0,sizeof(deep));
queue<int > q;
q.push(s);
deep[s]=1;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=head[u];~i;i=mp[i].next){
int to=mp[i].to;
if(mp[i].flow&&!deep[to]){ //注意条件;
deep[to]=deep[u]+1;
q.push(to);
}
}
}
return deep[t];
}
int dfs(int u, int f)
{
if(u==t) return f;
int ret=0;
for(int i=head[u];~i;i=mp[i].next){
int to=mp[i].to;
int val=mp[i].flow;
if(val&&deep[to]==deep[u]+1) { //注意条件;
int d = dfs(to, min(f, val));
ret += d, f -= d, mp[i].flow -= d, mp[i ^ 1].flow += d;
}
}
if(!ret) deep[u]=-1; //炸点;
return ret;
}
int main()
{
int n,m,x,y,val;
memset(head,-1,sizeof(head));
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=0;i<m;++i){
scanf("%d%d%d",&x,&y,&val);
add(x,y,val);
add(y,x,0);
}
int ans=0;
while(bfs()){
ans+=dfs(s,inf);
}
printf("%d\n",ans);
return 0;
}