标签:保存 pre div ++ 分析 调用 front 函数 while
struct Edge { int from,to,flow,cap; Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){} }; struct EdmonsKarp() { int n,m; vector<Edge> edges; vector<int> G[maxn]; int a[maxn]; int p[maxn]; void init(int n){ for(int i=0;i<n;i++) G[i].clear(); edges.clear(); } } void AddEdge(int from,int to,int cap) //邻接表形式保存图 ,感谢耀神昨天的讲解,这个Edge明白了是邻接表的变形 { edges.push_back(Edge(from,to,cap,0)); edges.push_back(Edge(to,from,0,0)); m=edges.size(); G[from].push_back(m-2); G[to].push_back(m-1); } int Maxflow(int s,int t) { int flow=0; for(;;) { memset(a,0,sizeof(a)); queue<int> Q; Q.push(s); a[s]=inf; while(!Q.empty()) { //整个while循环用来找一条增广路当中的最小残余量 int x=front(); Q.pop(); for(int i=0;i<G[x].size();i++) { Edge& e=G[x][i]; if(!a[e.to]&&e.cap>e.flow)//每调用一条边,比较这条边的残量和其父节点的残量大小 { //把最小残量保存到当前结点中 a[e.to]=min(a[x],e.cap-e.flow); p[e.to]=G[x][i]; //p数组记录到当前结点的前一条边的编号 Q.push(e.to); } } if(a[t]) //如果到达汇点了结束寻找 break; if(!a[t]) //a数组肯定是一个全局变量,由于每调用一次这个函数只能求出一条增广路增加的量 break; //每次都把a[i]标记,所以当源结点的所有子节点都被标记后,自然到达不了汇点 for(int u=t;u!=s;u=edges[p[u].from]) //而每一次函数调用后汇点都要被更新为0,所以当a[t]==0时候 { //就是所有的增广路都被跑完的时候 edges[p[u]].flow+=a[t]; edges[p[u]^1].flow-=a[t]; } flow+=a[t]; return flow; } }
标签:保存 pre div ++ 分析 调用 front 函数 while
原文地址:https://www.cnblogs.com/rainyskywx/p/9975639.html