[C++] 纯文本查看 复制代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef pair<int,int>PII;
void solve(){
int n,m,s,t,idx=0;
cin>>n>>m>>s>>t;
vector<int>h(n+10,-1),ne(m*2+10),e(m*2+10),c(m*2+10),h2(n+10);
auto add=[&](int a,int b,int c2){
e[idx]=b,ne[idx]=h[a],c[idx]=c2,h[a]=idx++;
};
for(int i=1,a,b,c;i<=m;i++){
cin>>a>>b>>c;
add(a,b,c);
add(b,a,0);
}
vector<int>d(n+10);
auto bfs=[&]()->bool{
fill(d.begin(),d.end(),0);
queue<int>q;
d[s]=1;
q.push(s);
while(q.size()){
auto t1=q.front();
q.pop();
for(int i=h[t1];i!=-1;i=ne[i]){
if(d[e[i]]!=0||c[i]==0)continue;
q.push(e[i]);
d[e[i]]=d[t1]+1;
if(e[i]==t)return true;
}
}
return false;
};
auto dfs=[&](auto dfs,int u,int mf)->int{
if(u==t)return mf;
int sum=0;
for(int i=h2[u];i!=-1;i=ne[i]){
h2[u]=i;//记录一下从u最后到的一次是哪里
//如果mf>=c[i] 这条边就已经用完了,另一条路径还到u这就直接去h2[u],前面u到其他走过的肯定走满了
//如果mf<c[i] 这个边没用完,如果h2记录后面的就错了,但是边没用完,mf用完了,走if(mf==0)break; 所以这两行要不一起在,要不一起不在,不然错
if(d[e[i]]==d[u]+1 && c[i]){
int f=dfs(dfs,e[i],min(mf,c[i]));
c[i]-=f;
c[i^1]+=f;
sum+=f;
mf-=f;
if(mf==0)break;//流量已经用完了后面都给不了
}
}
if(sum==0)d[u]=0;//u节点跑完所有可能能到的点都还是0,证明一个都不能到,直接毁掉d[u]不让其他路径浪费时间了
return sum;
};
int ans=0;
while(bfs()){
h2=h;
ans+=dfs(dfs,s,1e18);
}
cout<<ans<<endl;
}
signed main(){
int t=1;ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
// cin>>t;
while(t--)solve();
return 0;
}