马上要出发去北京蓝桥杯国赛啦,网络最大流还不是特别熟,就刷了两道裸题,怕模板记不住(毕竟是类OI赛制),开个博客记录一下方便火车上手机看,毕竟还是自己写的代码看起来更舒服一点,如果能帮到其他人或有大佬指出问题那就更好啦
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct edge
{
int val,to,nxt;
}e[100005*2];
int head[100005],deep[100005];
int total=0,n,m,s,t;
const int MAX=0x3f3f3f3f;
void adde(int ui,int vi,int wi)//链式前向星,如果要用异或取反边要从0或2开始,不能从1开始
{
e[total].nxt=head[ui];
e[total].val=wi;
e[total].to=vi;
head[ui]=total++;
}
bool bfs()//分层
{
memset(deep,0x3f,sizeof(deep));//每次清空层级
deep[s]=0;
queue<int> q;
q.push(s);
while(!q.empty())
{
int now=q.front();
q.pop();
for(int i=head[now];i!=-1;i=e[i].nxt)
{
if(deep[e[i].to]>deep[now]+1&&e[i].val>0)//更新能到达点的最小层,前提是还有流量
{
deep[e[i].to]=deep[now]+1;
q.push(e[i].to);
}
}
}
return deep[t]!=MAX;//如果到t已经没流量了说明算法结束了
}
int dfs(int u,int flow)
{
if(u==t)
return flow;
int tmpf=0;
for(int i=head[u];i!=-1&&flow>0;i=e[i].nxt)//一直查看邻点的,如果总流量没了也推出
{
if(deep[u]+1==deep[e[i].to]&&e[i].val>0)//只能到下一层的点,这也是dinic的核心,当然流量也要保证还有
{
int tmp=dfs(e[i].to,min(flow,e[i].val));//看能不能把最大流过去,管子受限就只能传管子那么多的流量
e[i].val-=tmp;//正反边一加一减
e[i^1].val+=tmp;
flow-=tmp;
tmpf+=tmp;
}
}
if(!tmpf)//炸点优化,如果当前点都不能更新最大流的值了就把他“炸掉”
deep[u]=-2;
return tmpf;
}
int main()
{
int ans=0;
memset(head,-1,sizeof(head));
scanf("%d %d %d %d",&n,&m,&s,&t);
for(int i=0;i<m;i++)
{
int ui,vi,wi;
scanf("%d %d %d",&ui,&vi,&wi);
adde(ui,vi,wi);
adde(vi,ui,0);
}
while(bfs())
ans+=dfs(s,MAX);
printf("%d\n",ans);
return 0;
}