https://www.luogu.com.cn/problem/P4722
思路:卡,就硬卡。
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2e3+5;
const int maxm=2e5+5;
struct Edge
{
int to,nxt,f;
}edge[maxm<<1];
int n,m,s,t,tot;
int head[maxn],depth[maxn],rest[maxn],inque[maxn],cnt[maxn<<1];
struct cmp
{
inline bool operator ()(int a,int b)const
{
return depth[a]<depth[b];
}
};
priority_queue<int,vector<int>,cmp> q;
inline int read() //注意 该快读省去了负数的情况
{
char ch=getchar();
while(ch<'0'||ch>'9')
ch=getchar();
int ans=0;
while(ch>='0'&&ch<='9')
{
ans=(ans<<3)+(ans<<1)+ch-48;
ch=getchar();
}
return ans;
}
inline void addedge(int u,int v,int dis)
{
edge[++tot].to=v,edge[tot].f=dis;
edge[tot].nxt=head[u];
head[u]=tot;
edge[++tot].to=u,edge[tot].f=0;
edge[tot].nxt=head[v];
head[v]=tot;
}
void bfs()
{
queue<int> que;
memset(cnt,0,sizeof(cnt));
memset(depth,0,sizeof(depth));
depth[t]=1,cnt[1]=1;
que.push(t);
while(!que.empty())
{
int u=que.front();
que.pop();
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(!depth[v])
{
depth[v]=depth[u]+1;
++cnt[depth[v]];
que.push(v);
}
}
}
}
inline void out(int u)//推流
{
int flow;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(edge[i].f&&depth[u]==depth[v]+1)
{
flow=min(edge[i].f,rest[u]); //边的流量 u点的余流
edge[i].f-=flow;
edge[i^1].f+=flow;
rest[u]-=flow;
rest[v]+=flow;
if(v!=s&&v!=t&&!inque[v])//如果v不是源点不是汇点且不在优先队列中则入队
q.push(v),inque[v]=1;
if(!rest[u]) //节点u 已没有余流可推
break;
}
}
return ;
}
inline void relable(int u)//修改深度
{
depth[u]=INF;
for(int i=head[u];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(edge[i].f&&depth[v]+1<depth[u])
depth[u]=depth[v]+1;
}
return ;
}
int hlpp()
{
bfs();
if(depth[s]==0) //可以判断一下连通性
return 0;
depth[s]=n;
memset(rest,0,sizeof(rest));
memset(inque,0,sizeof(inque));
for(int i=head[s];i;i=edge[i].nxt)//源点s向 邻接点推流
{
int u=edge[i].to;
if(edge[i].f)
{
rest[u]+=edge[i].f;
swap(edge[i].f,edge[i^1].f);
if(u!=s&&u!=t&&!inque[u])
q.push(u),inque[u]=1;
}
}
while(!q.empty()) //按照高度 依次推流
{
int u=q.top();
q.pop();
inque[u]=0;
out(u); //推流
if(rest[u])
{
if(--cnt[depth[u]]==0)
{
for(int i=1;i<=n;i++)
if(i!=s&&i!=t&&depth[i]>depth[u]&&depth[i]<=n)
depth[i]=n+1;
}
relable(u);
++cnt[depth[u]];
q.push(u);
inque[u]=1;
}
}
return rest[t];
}
int main()
{
while(~scanf("%d %d %d %d",&n,&m,&s,&t))
{
tot=1;
memset(head,0,sizeof(head));
int u,v,w;
for(int i=0;i<m;i++)
{
u=read(),v=read(),w=read();
// scanf("%d %d %d",&u,&v,&w);
addedge(u,v,w);
}
printf("%d\n",hlpp());
}
}