//5e3+5不够,以后都+10 保险起见
#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=210,maxe=5e3+5;
typedef long long ll;
int n,m,s,t;
ll ans,tot,head[maxn<<1],d[maxn<<1];
struct edge{
ll to,nex,w;
}e[maxe<<1];
void adde(int u,int v,int w){
e[++tot]={v,head[u],w};
head[u]=tot;
}
bool bfs(){//s到t
int u;
queue<int>q;
memset(d,0,sizeof(d));
q.push(s),d[s]=1;
while(!q.empty()){
u=q.front(),q.pop();
for(int i=head[u];i;i=e[i].nex){
int v=e[i].to;
if(e[i].w&&!d[v]){//d[v]没到达过
q.push(v);
d[v]=d[u]+1;//按边数分层
if(v==t) return true;//找到 可到达终点的路 了
}
}
}
return false;
}
ll dfs(int u,ll in){
if(u==t) return in;
ll out=0;
for(int i=head[u];i&∈i=e[i].nex){//in!=0说明还有余量
int v=e[i].to;
if(e[i].w&&d[v]==d[u]+1){
//==是为了:每次尝试给予时,只往下一层走,防止混乱
ll res=dfs(v,min(in,e[i].w));
//in是该路径走到当前位置的最小流,
e[i].w-=res;
e[i^1].w+=res;//^求反向边
in-=res;
out+=res;
}
}
if(out==0) d[u]=0;//与t不连通,下次可以不用考虑该路
return out;
}
ll dinic(int s,int t){
ll flow,maxf=0;
while(bfs())
while(flow=dfs(s,inf))
maxf+=flow;
return maxf;
}
int main(){
int u,v,w;
scanf("%d%d%d%d",&n,&m,&s,&t);
tot=1;//tot为什么初始化不为0,方便异或找 奇偶 反向边?
memset(head,0,sizeof(head));
for(int i=1;i<=m;i++){
scanf("%d%d%d",&u,&v,&w);
adde(u,v,w);
adde(v,u,0);
}
printf("%lld\n",dinic(s,t));
}
P3376网络流dinic
最新推荐文章于 2024-10-04 05:48:57 发布