题目描述:
给出一个网络图,以及其源点和汇点,求出其网络最大流。
题解:
1.Dinic
Dinic算法可用于求最大流。
算法过程:
bfs分层+dfs搜最大流。
注意:残余网络。
代码:
#include<queue> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 10050 #define M 100050 #define ll long long int n,m,s,t,hed[N],cnt=-1,cur[N]; const int inf = 0x3f3f3f3f; struct EG { int to,nxt; ll vl; }e[2*M]; void ae(int f,int t,ll v) { e[++cnt].to = t; e[cnt].vl = v; e[cnt].nxt = hed[f]; hed[f] = cnt; } int dep[N]; bool bfs() { memset(dep,0x3f,sizeof(dep)); memcpy(cur,hed,sizeof(cur)); dep[s]=0; queue<int>q; q.push(s); while(!q.empty()) { int u = q.front(); q.pop(); for(int j=hed[u];~j;j=e[j].nxt) { int to = e[j].to; if(e[j].vl&&dep[to]>dep[u]+1) { dep[to]=dep[u]+1; q.push(to); } } } if(dep[t]!=inf)return 1; return 0; } ll dfs(int u,ll lim) { if(!lim||u==t)return lim; ll fl=0,f; for(int j=cur[u];~j;j=e[j].nxt) { cur[u]=j; int to = e[j].to; if(dep[to]==dep[u]+1&&(f=dfs(to,min(lim,e[j].vl)))) { fl+=f; lim-=f; e[j].vl-=f; e[j^1].vl+=f; if(!lim)break; } } return fl; } ll dinic() { ll ret = 0; while(bfs()) ret+=dfs(s,inf); return ret; } int main() { memset(hed,-1,sizeof(hed)); scanf("%d%d%d%d",&n,&m,&s,&t); for(int f,t,v,i=1;i<=m;i++) { scanf("%d%d%d",&f,&t,&v); ae(f,t,1ll*v),ae(t,f,0); } printf("%lld ",dinic()); return 0; }