基本思路:在求图的最大流时,首先用bfs把图分层,分层时注意流量是否大于零,和该点是否已分层。每一次分层都需要重置level数组,如果分层后,终点没有被分层,说明没有增广路了,,之后用dfs进行增广路搜索,如果流量不为零, 并且该节点到下一个节点,正好为差为1,就在可以在搜索增广路,如果增广路搜索到的流量大于零,就要构建残余网络,就返回该流量,若找不到返回零。
#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include <stack>#include <string>#include <set>#include <map>#include <cstdlib>#include <cmath>#include <algorithm>#define MAXX 300#define INF 0x7fffffffstruct node{int to, cal, rev;};using namespace std;vector<node>g[MAXX];int level[MAXX];int m ,n;int iter[MAXX];void add(int fr, int to, int cal){int pos = -1;for (int i=0; i<g[fr].size(); i++)if (g[fr][i].to == to){pos = i;break;}if (pos != -1)g[fr][pos].cal += cal;else{g[fr].push_back((node){to, cal, g[to].size()});g[to].push_back((node){fr, 0, g[fr].size()-1});return ;}}void bfs(){queue<int>q;memset(level, -1, sizeof(level));level[1] = 0;q.push(1);while (!q.empty()){int u = q.front();q.pop();for (int i=0; i<g[u].size(); i++){node &e = g[u][i];if (e.cal > 0 && level[e.to] < 0){level[e.to] = level[u]+1;q.push(e.to);}}}while (!q.empty())q.pop();}int dfs(int v, int f){if (v == n)return f;for (int &i=iter[v]; i<g[v].size(); i++){node &e = g[v][i];if (e.cal>0 && level[e.to] == level[v]+1){int d = dfs(e.to, min(f, e.cal)); //继续寻找增广路的最大流量if (d>0){e.cal -= d;g[e.to][e.rev].cal += d; //更新边的流量。return d;}}}return 0;}int max_flow(int s){int flow = 0;while (1){bfs();if (level[n] <= 0)return flow;int f;memset(iter, 0, sizeof(iter));while ((f = dfs(s, INF)) > 0) //搜索增广路的最小流量。flow += f;}}int main(){while (scanf("%d%d",&m, &n)!=EOF){while (m--){int fr, to, cal;scanf("%d%d%d", &fr, &to, &cal);add(fr, to, cal);}printf("%d\n", max_flow(1));for (int i=1; i<=n; i++)g[i].clear();}return 0;}
2037

被折叠的 条评论
为什么被折叠?



