洛谷上过了,uoj上过不去 #26
// Problem: #680. 网络最大流
// Contest: UOJ
// URL: https://uoj.ac/problem/680
// Memory Limit: 512 MB
// Time Limit: 5000 ms
#include<stdio.h>
#include<stack>
#include<ctype.h>
namespace fasti{
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*(p1++);}
inline void read(long long&x){
char c=getc(),f=0;
for(;!isdigit(c);c=getc())f^=!(c^'-');
for(x=0;isdigit(c);c=getc())x=x*10+(c^48);
if(f)x=-x;--p1;
}
inline void read(int&x){
char c=getc(),f=0;
for(;!isdigit(c);c=getc())f^=!(c^'-');
for(x=0;isdigit(c);c=getc())x=x*10+(c^48);
if(f)x=-x;--p1;
}
template<typename T,typename... Args>
inline void read(T&x,Args&...args){read(x),read(args...);}
}
using fasti::getc;
using fasti::read;
const int maxn=1200,maxm=120000,inf=0x3f3f3f3f;
struct{
int v;long long c;int nxt;
}edge[maxm<<1];
int head[maxn|1],lv,n,s,t,ht[maxn|1];
long long ex[maxn|1],gap[maxn<<1|1];
std::stack<int>stk[maxn<<1|1];
inline long long min(long long x,long long y){return x<y?x:y;}
inline long long max(long long x,long long y){return x>y?x:y;}
inline void addedge(int u,int v,long long c){
static int tot=0;
edge[tot]={v,c,head[u]},head[u]=tot++,edge[tot]={u,0,head[v]},head[v]=tot++;
}
bool push(int u){
int v;long long c;
for(int i=head[u];~i;i=edge[i].nxt){
v=edge[i].v,c=edge[i].c;
if(!c||(u!=s)&&ht[u]!=ht[v]+1)continue;
c=(u==s)?c:min(c,ex[u]);
if(v!=s&&v!=t&&!ex[v])stk[ht[v]].push(v),lv=max(lv,ht[v]);
ex[u]-=c,ex[v]+=c,edge[i].c-=c,edge[i^1].c+=c;
if(!ex[u])return 0;
}
return 1;
}
void relabel(int u){
ht[u]=inf;
for(int i=head[u];~i;i=edge[i].nxt)if(edge[i].c)ht[u]=min(ht[u],ht[edge[i].v]);
if(++ht[u]<n)stk[ht[u]].push(u),lv=max(lv,ht[u]),++gap[ht[u]];
}
bool bfs(){
for(int i=1;i<=n;++i)ht[i]=inf;
static int q[maxn];
int l=0,r=0;q[r++]=t,ht[t]=0;
for(;l<r;++l)
for(int i=head[q[l]];~i;i=edge[i].nxt){
if(q[l]==t&&edge[i].v==s)ex[t]+=edge[i^1].c;
else if(edge[i^1].c&&ht[edge[i].v]==inf)
ht[edge[i].v]=ht[q[l]]+1,q[r++]=edge[i].v;
}
return ht[s]!=inf;
}
int maxht(){
for(;(~lv)&&stk[lv].empty();--lv);
return (~lv)?stk[lv].top():0;
}
long long HLPP(){
if(!bfs())return ex[t];
for(int i=0;i<n;++i)gap[i]=0;
for(int i=1;i<=n;++i)if(ht[i]<n)++gap[ht[i]];
ht[s]=n,push(s);
for(int i=head[s];~i;i=edge[i].nxt)
if(edge[i].c){
if(edge[i].v!=t&&!ex[edge[i].v])
stk[ht[edge[i].v]].push(edge[i].v),lv=max(lv,ht[edge[i].v]);
ex[edge[i].v]+=edge[i].c,edge[i^1].c=edge[i].c,edge[i].c=0;
}
for(int u;u=maxht();){
stk[lv].pop();
if(push(u)){
if(!(--gap[ht[u]]))
for(int i=1;i<=n;++i)
if(i!=s&&i!=t&&ht[i]>ht[u]&&ht[i]<=n)
ht[i]=n+1;
relabel(u);
}
}
return ex[t];
}
signed main(){
int m,u,v;long long c;
read(n,m,s,t);
for(int i=1;i<=n;head[i++]=-1);
for(;m--;addedge(u,v,c))read(u,v,c);
printf("%lld",HLPP());
return 0;
}