标签:pre 最大 增广 int flow maxn delta
EK算法
复杂度O(n*m^2)
EK算法思路:1、利用bfs寻找增广路 2、若存在增广路,维护最大流
#include<iostream> #include<queue> #include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int inf = 0x7fffffff; const int maxn = (int)2e2 + 10; int n, m; //顶点数和边数 int G[maxn][maxn]; //存图G[i][j]=c 为点i到点j的边的容量为c int pre[maxn]; //存储增广路,记录前驱,pre[i]=j为i的前驱为j int flow[maxn]; //寻找增广路使记录流向每个节点的流量,flow[u]=k为起始点s流向u点的流量为k int bfs(int s,int t){ //寻找一条从s到t的增广路,如果找到返回增广路的可行流,如果没找到返回-1用于标记 queue<int> q; for (int i = 0; i <= n; i++) pre[i] = -1; pre[s] = 0; flow[s] = inf; q.push(s); while (!q.empty()){ int p = q.front(); q.pop(); if (p == t) break; //找到一条增广路 for (int u = 1; u <= n; u++){ //不是原点 if (u!=s && pre[u] == -1 && G[p][u] > 0){ //该点没被走过并且该点的流量大于0 pre[u] = p; flow[u] = min(flow[p],G[p][u]); q.push(u); } } } if (pre[t] == -1) return -1; return flow[t]; } int EK(int s,int t){ //计算最大流,EK算法,复杂度O(n*m^2) int maxsum = 0, delta; while ((delta=bfs(s,t))!=-1){ //delta = bfs(s, t); //if (delta == -1) break; int p = t; //从终点出发 while (p != s){ G[pre[p]][p] -= delta; //正向边 G[p][pre[p]] += delta; //反向边 p = pre[p]; //更新当前点 } maxsum += delta; } return maxsum; } int main() { int a, b, c; cin >> n >> m; memset(G, 0, sizeof(G)); memset(flow, 0, sizeof(flow)); for (int i = 0; i < m; i++){ scanf("%d%d%d",&a,&b,&c); G[a][b] += c; } printf("%d\n",EK(1,n)); return 0; }View Code
标签:pre,最大,增广,int,flow,maxn,delta 来源: https://www.cnblogs.com/looeyWei/p/10455942.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。