阿里云域名注册好了怎么做网站,建网站需要哪些硬件,安徽设计网站建设,网站租房做公寓题意#xff1a;1是源点#xff0c;m是汇点#xff0c;求出来最大流量#xff0c;没什么好说的就是练习最大流的模板题 ************************************************************** 先用Edmonds-Karp的算法做一下试试吧重边贡献了 1W#xff0c;要加上所有的重边才算…题意1是源点m是汇点求出来最大流量没什么好说的就是练习最大流的模板题 ************************************************************** 先用Edmonds-Karp的算法做一下试试吧重边贡献了 1W要加上所有的重边才算是两点间最大流量 *********************************************************************************************************************** /************************************//** 使用Edmonds-Karp 最短增广路算法*//** 邻接矩阵实现 *//** 2015/8/7/9:39 *//************************************/#includestdio.h#includestring.h#includequeue#includealgorithmusing namespace std;const int MAXN 205;const int oo 1e97;///1是源点M是汇点N条边int G[MAXN][MAXN], M, N;int pre[MAXN];///记录每个点的前驱也就是父节点bool used[MAXN];///s代表源点e代表汇点,可以到达汇返回true否则返回falsebool BFS(int s, int e){ memset(used, false, sizeof(used)); queueint Q; Q.push(s); used[s] true; while(Q.size()) { s Q.front();Q.pop(); if(s e) return true; for(int i1; iM; i) { if(G[s][i] !used[i]) { pre[i] s; used[i] true; Q.push(i); } } } return false;}int Karp(int s, int e){ int MaxFlow 0; while( BFS(s, e) true ) {///如果有增量 int MinFlow oo, v; v e; while(v ! s) {///求出来路径上最小流量 MinFlow min(MinFlow, G[pre[v]][v]); v pre[v]; } MaxFlow MinFlow; v e; while(v ! s) {///边上的所有点减去最小流量反边增加流量 G[pre[v]][v] - MinFlow; G[v][pre[v]] MinFlow; v pre[v]; } } return MaxFlow;}int main(){ while(scanf(%d%d, N, M) ! EOF) { int i, u, v, c; memset(G, false, sizeof(G)); for(i1; iN; i) { scanf(%d%d%d, u, v, c); G[u][v] c;///有重边两点间应该算上所有边 } printf(%d\n, Karp(1, M)); } return 0;} View Code 邻接表实现 *********************************************************************************************************************** /************************************//// 使用Edmonds-Karp 最短增广路算法/// 邻接表实现/// 2015年8月7日10:13:55/************************************/#includestdio.h#includestring.h#includequeue#includealgorithmusing namespace std;const int MAXN 205;const int oo 1e97;struct Edge{int u, v, Flow, next;}e[MAXN1];int Head[MAXN], cnt;int pre[MAXN], used[MAXN];void InIt(){ memset(Head, -1, sizeof(Head)); cnt 0;}void AddEdge(int u, int v, int Flow){ e[cnt].u u; e[cnt].v v; e[cnt].Flow Flow; e[cnt].next Head[u]; Head[u] cnt;}bool BFS(int s, int End){ memset(used, false, sizeof(used)); memset(pre, -1, sizeof(pre)); queueint Q; Q.push(s); used[s] true; while(Q.size()) { s Q.front();Q.pop(); if(s End)return true; for(int iHead[s]; i!-1; ie[i].next) { if(e[i].Flow used[e[i].v] false) { used[e[i].v] true; pre[e[i].v] i;///记录的是上面的边的位置 Q.push(e[i].v); } } } return false;}int Karp(int s, int End){ int MaxFlow 0; while(BFS(s, End) true) { int MinFlow oo, v; v pre[End]; while(v ! -1) { MinFlow min(MinFlow, e[v].Flow); v pre[e[v].u];///上个点来的位置 } MaxFlow MinFlow; v pre[End]; while(v ! -1) { e[v].Flow - MinFlow; e[v^1].Flow MinFlow; v pre[e[v].u]; } } return MaxFlow;}int main(){ int N, M; while(scanf(%d%d, N, M) ! EOF) { int i, u, v, Flow; InIt(); for(i1; iN; i) { scanf(%d%d%d, u, v, Flow); AddEdge(u, v, Flow); AddEdge(v, u, 0);///先添加一条反边的流量是0 } printf(%d\n, Karp(1, M)); } return 0;} code Dinic实现 ************************************************************************************************************************ #includestdio.h#includestring.h#includequeueusing namespace std;const int MAXN 205;const int oo 1e97;struct Edge{int u, v, flow, next;}edge[MAXN*MAXN];int Head[MAXN], cnt;int layer[MAXN];///分层int Start, End;///源点汇点void AddEdge(int u, int v, int flow){ edge[cnt].u u; edge[cnt].v v; edge[cnt].flow flow; edge[cnt].next Head[u]; Head[u] cnt;}bool BfsLayer()///使用广搜进行分层{ bool used[MAXN]{0};queueint Q; memset(layer, -1, sizeof(layer)); Q.push(Start); used[Start] true; layer[Start] 0; while(Q.size()) { int s Q.front();Q.pop(); if(s End)return true; for(int iHead[s]; i!-1; iedge[i].next) { int v edge[i].v; if(edge[i].flow !used[v]) { used[v] true; layer[v] layer[s] 1; Q.push(v); } } } return false;}int dfs(int u, int MaxFlow){///MaxFlow 记录的是这条路径上能经过的最大流量 if(u End)return MaxFlow; int uFlow 0;///这个点最多能经过多少流量 for(int iHead[u]; i!-1; iedge[i].next) { int v edge[i].v, flow edge[i].flow; if(layer[v]-1 layer[u] flow) { flow min(MaxFlow-uFlow, flow); flow dfs(v, flow); edge[i].flow - flow; edge[i^1].flow flow; uFlow flow; if(uFlow MaxFlow) break;///已经等于最大流量的时候注意结束 } } return uFlow;}int Dinic()///用dinic算法求最大流{ int MaxFlow 0; while(BfsLayer() true) { MaxFlow dfs(Start, oo); } return MaxFlow;}int main(){ int N, M; while(scanf(%d%d, N, M) ! EOF) { int i, u, v, flow; Start 1, End M, cnt 0; memset(Head, -1, sizeof(Head)); for(i1; iN; i) { scanf(%d%d%d, u, v, flow); AddEdge(u, v, flow); AddEdge(v, u, 0); } printf(%d\n, Dinic()); } return 0;} View Code SAP实现 ************************************************************************************************************************* #includestdio.h#includestring.h#includequeueusing namespace std;const int MAXN 205;const int oo 1e97;struct Edge{int u, v, flow, next;}edge[MAXN*MAXN];int Head[MAXN], cnt;int Layer[MAXN];///分层int start, End;///源点汇点int cur[MAXN], Stack[MAXN],gap[MAXN];int sumV;///节点的总个数void AddEdge(int u, int v, int flow){ edge[cnt].u u; edge[cnt].v v; edge[cnt].flow flow; edge[cnt].next Head[u]; Head[u] cnt;}void BFS(){ memset(Layer, -1, sizeof(Layer)); memset(gap, 0, sizeof(gap)); queueint Q; Q.push(End); Layer[End] 0, gap[0] 1; while(Q.size()) { int u Q.front(); Q.pop(); for(int jHead[u]; j!-1; jedge[j].next) { int v edge[j].v; if(Layer[v] -1) { Layer[v] Layer[u] 1; gap[Layer[v]]; Q.push(v); } } }}int SAP(){ int j, top0, u start, MaxFlow0; BFS(); memcpy(cur, Head, sizeof(Head)); while(Layer[start] sumV) {///源点的层次小于总结点数,汇点是0层 if(u End) { int MinFlow oo, location;///记录下最小流量边的位置出栈时候用 for(j0; jtop; j) { int i Stack[j]; if(MinFlow edge[i].flow) { MinFlow edge[i].flow; location j; } } for(j0; jtop; j) {///所有的边减去路径上的最小流量 int i Stack[j]; edge[i].flow - MinFlow; edge[i^1].flow MinFlow; } MaxFlow MinFlow; top location;///退栈 u edge[Stack[top]].u; } else if(gap[Layer[u]-1] 0) break;///u所在的层下面的层没有了出现了断层也就没有了可行弧 for(jcur[u]; j!-1; jedge[j].next) {///如果u有可行弧就停止 if(Layer[u]Layer[edge[j].v]1 edge[j].flow) break; } if(j ! -1) {///找到了可行弧 cur[u] j;///u点的可行弧是j Stack[top] j;///记录下这条边 u edge[j].v; } else {///没有找到可行弧修改标号 int MinIndex sumV; for(jHead[u]; j!-1; jedge[j].next) {///查找与u相连的最小的层是多少 if(edge[j].flow MinIndex Layer[edge[j].v]) {///记录下这条可行弧,下次可以直接访问这条边 MinIndex Layer[edge[j].v]; cur[u] j; } } gap[Layer[u]] - 1;///u改变层所以u原来所在层的点数减去1 Layer[u] MinIndex 1; gap[Layer[u]] 1; if(u ! start) {///返回上一层 u edge[Stack[--top]].u; } } } return MaxFlow;}int main(){ int N, M; while(scanf(%d%d, N, M) ! EOF) { int i, u, v, flow; sumV M; start 1, End M, cnt 0; memset(Head, -1, sizeof(Head)); for(i1; iN; i) { scanf(%d%d%d, u, v, flow); AddEdge(u, v, flow); AddEdge(v, u, 0); } printf(%d\n, SAP()); } return 0;} View Code转载于:https://www.cnblogs.com/liuxin13/p/4709956.html