存个板子
#include<bits/stdc++.h>
#define ll long long
#define re register
#define gc get_char
#define cs const
namespace IO{
inline char get_char(){
static cs int Rlen=1<<20|1;
static char buf[Rlen],*p1,*p2;
return (p1==p2)&&(p2=(p1=buf)+fread(buf,1,Rlen,stdin),p1==p2)?EOF:*p1++;
}
inline int getint(){
re char c;
while(!isdigit(c=gc()));re int num=c^48;
while(isdigit(c=gc()))num=(num+(num<<2)<<1)+(c^48);
return num;
}
}
using namespace IO;
struct edge{
int to,cap,rev;
edge(cs int &_to,cs int &_cap,cs int &_rev):to(_to),cap(_cap),rev(_rev){}
};
cs int N=1e4+4;
int n,m;
std::vector<edge> G[N];
typedef std::vector<edge>::iterator iter;
iter cur[N];
inline void addedge(int u,int v,int val){
G[u].push_back(edge(v,val,G[v].size()));
G[v].push_back(edge(u,0,G[u].size()-1));
}
int S,T;
int lev[N],gap[N];
inline void BFS(){
memset(lev+1,-1,sizeof(int)*n);
memset(gap,0,sizeof(int)*(n+2));
lev[T]=gap[1]=1;
std::queue<int,std::list<int> > q;
q.push(T);
while(!q.empty()){
int u=q.front();q.pop();
for(iter re e=G[u].begin();e!=G[u].end();++e){
int v=e->to;
if(~lev[v])continue;
q.push(v);
++gap[lev[v]=lev[u]+1];
}
}
}
int dfs(int u,cs int &flow){
if(u==T)return flow;
int ans=0;
for(iter &e=cur[u];e!=G[u].end();++e){
if(e->cap&&lev[e->to]+1==lev[u]){
int delta=dfs(e->to,std::min(flow-ans,e->cap));
if(delta){
e->cap-=delta;
G[e->to][e->rev].cap+=delta;
ans+=delta;
}
if(ans==flow)return ans;
}
}
--gap[lev[u]];
if(gap[lev[u]]==0)lev[S]=n+1;
++lev[u];
++gap[lev[u]];
return ans;
}
int ISAP(){
int mxflow=0;
BFS();
while(lev[S]<=n){
for(int re i=1;i<=n;++i)cur[i]=G[i].begin();
mxflow+=dfs(S,0x3f3f3f3f);
}
return mxflow;
}
signed main(){
// freopen("lx.in","r",stdin);
n=getint(),m=getint();
S=getint(),T=getint();
for(int re i=1;i<=m;++i){
int u=getint(),v=getint(),val=getint();
addedge(u,v,val);
}
std::cout<<ISAP()<<"\n";
return 0;
}