P4722 【模板】最大流
阿新 • • 發佈:2018-11-10
今日心血來潮,打算學習hlpp
然後學了一陣子。發現反向邊建錯了。容量並不是0.qwq
然後就荒廢了一晚上。
演算法流程的話。有時間補上
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<queue> using std::min; using std::queue; using std::vector; using std::priority_queue; const int N=3e4,M=3e5; const int inf=0x3f3f3f3f; int head[N],nxt[M<<1],flow[M<<1],p[M<<1],tail=-1; int H[N],gap[M<<1],e[N]; bool inq[N]; int n,m,s,t; void add(int a,int b,int c) { p[++tail]=b; flow[tail]=c; nxt[tail]=head[a]; head[a]=tail; } struct compare { bool operator()(int A,int B)const{ return H[A]<H[B]; } }; priority_queue<int,vector<int>,compare> q; bool bfs() { queue<int>Q; memset(H,0x3f,sizeof(H)); H[t]=0;Q.push(t); while(!Q.empty()) { int pas=Q.front();Q.pop(); for(int i=head[pas];i!=-1;i=nxt[i]) if(flow[i^1]&&H[p[i]]>H[pas]+1) { H[p[i]]=H[pas]+1; Q.push(p[i]); } } return H[s]!=inf; } void push_flow(int now) { for(int i=head[now];i!=-1;i=nxt[i]) if(flow[i]&&H[p[i]]+1==H[now]) { int F=min(e[now],flow[i]); flow[i]-=F;flow[i^1]+=F; e[now]-=F;e[p[i]]+=F; if(p[i]!=s&&p[i]!=t&&!inq[p[i]]) { q.push(p[i]); inq[p[i]]=true; } if(!e[now]) break; } return ; } void reset(int now) { H[now]=inf; for(int i=head[now];i!=-1;i=nxt[i]) if(flow[i]&&H[p[i]]+1<H[now]) H[now]=H[p[i]]+1; return ; } int hlpp() { if(!bfs()) return 0; H[s]=n; memset(gap,0,sizeof(gap)); for(int i=1;i<=n;i++) if(H[i]<inf) gap[H[i]]++; for(int i=head[s];i!=-1;i=nxt[i]) if(flow[i]) { int pas=flow[i]; flow[i]-=pas;flow[i^1]+=pas;e[s]-=pas;e[p[i]]+=pas; if(p[i]!=s&&p[i]!=t&&!inq[p[i]]) q.push(p[i]),inq[p[i]]=true; } while(!q.empty()) { int pas=q.top(); inq[pas]=false;q.pop(); push_flow(pas); if(e[pas]) { gap[H[pas]]--; if(!gap[H[pas]]) for(int i=1;i<=n;i++) if(i!=s&&i!=t&&H[i]>=H[pas]&&H[i]<n+1) H[i]=n+1; reset(pas); gap[H[pas]]++; q.push(pas);inq[pas]=true; } } return e[t]; } int main() { scanf("%d%d%d%d",&n,&m,&s,&t); int a,b,c; for(int i=1;i<=n;i++) head[i]=-1; for(int i=1;i<=m;i++) { scanf("%d%d%d",&a,&b,&c); add(a,b,c);add(b,a,0); } printf("%d",hlpp()); }