之前的Dinic板子只加了分层图优化,没有加-1优化和当前弧优化。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+50;
const long long INF=2e18;
int n,m,s,t,ecnt;
int dis[maxn],head[maxn];
long long ans=0;
struct mint {
int nxt,v;
long long w;
} e[maxn<<1];
inline void addline(int u,int v,long long w) {
e[++ecnt].nxt=head[u];
e[ecnt].v=v;
e[ecnt].w=w;
head[u]=ecnt;
}
int BFS() {
queue<int> q;
memset(dis,0,sizeof(dis));//每次寻找增广路径都需要将dis数组重置
dis[s]=1;
q.push(s);
while(!q.empty()) {
int now=q.front();
q.pop();
for(int i=head[now]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(e[i].w==0 || dis[v]) continue;
dis[v]=dis[now]+1;
q.push(v);
}
}
return dis[t];
}
long long DFS(int now,long long lim) { //point为当前遍历的节点,MAX为最大可行流量,MAX初始为INF
if(now==t || !lim) return lim; //当前点为汇点时返回即可
long long res=0;
for(int i=head[now]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(e[i].w==0 || dis[v]!=dis[now]+1) continue;
long long add=DFS(v,min(lim,e[i].w));
e[i].w-=add;
e[i^1].w+=add;
res+=add;
lim-=add;
if(!lim) break;
}
if(!res) dis[now]=-1;
return res;
}
int main() {
memset(head,-1,sizeof(head));
ecnt=-1;
scanf("%d%d%d%d",&n,&m,&s,&t);
for(int i=1; i<=m; ++i) {
int u,v;
long long w;
scanf("%d%d%lld",&u,&v,&w);
addline(u,v,w);
addline(v,u,0);
}
while(BFS()) { //当增广路径存在进行DFS
long long tmp=0;
while(tmp=DFS(s,INF)) ans+=tmp;
}
printf("%lld",ans);
return 0;
}