网络流
bfs:对整张网络图进行分层,dfs一次就要分一次层,因为在dfs后有些流量会变成0;
dfs:求从起点到终点的一条路径的最大流
dinic:分层成功后,然后跑dfs,再累加最大流
#include<bits/stdc++.h> using namespace std; int tot=1;//2,3一组 const int INF=0x7f7f7f; const int N=1e4+5; const int M=2e5+5;//两倍数组 双向边 int nex[M],head[N],to[M],from[M],cost[M],lev[N],s,t,n,m; queue<int >q; void add(int a,int b,int ww) { tot++; from[tot]=a; to[tot]=b; cost[tot]=ww; nex[tot]=head[a]; head[a]=tot; } bool bfs() { memset(lev,-1,sizeof(lev)); lev[s]=0; q.push(s); while(!q.empty()) { int u=q.front(); q.pop(); for(int i=head[u];i!=-1;i=nex[i]) { int v=to[i]; if(cost[i]!=0&&lev[v]==-1) lev[v]=lev[u]+1,q.push(v); } } if(lev[t]!=-1) return true; return false; } int dfs(int u,int flow) { if(u==t) return flow; int ret=flow; for(int i=head[u];i!=-1;i=nex[i]) { if(ret<=0) break; int v=to[i]; if(cost[i]&&lev[u]+1==lev[v]) { int k=dfs(v,min(cost[i],ret)); ret-=k; cost[i]-=k; cost[i^1]+=k; //异或运算:2k^1=(2k+1) (2k+1)^1=2k; } } return flow-ret;//最大限制 - 还剩的多少没流 } void dinic() { int ans=0; while(bfs()) { ans+=(dfs(s,INF)); } printf("%d ",ans); } int main() { int x,y,z; memset(head,-1,sizeof(head));//head赋值成-1是为了当前弧优化 scanf("%d%d%d%d",&n,&m,&s,&t); for(int i=1;i<=m;i++) scanf("%d%d%d",&x,&y,&z),add(x,y,z),add(y,x,0);//建反向边 为0 dinic(); }