• HDU 3549 Flow Problem(最大流)


    题目:

    Network flow is a well-known difficult problem for ACMers. Given a graph, your task is to find out the maximum flow for the weighted directed graph.

    Input:

    The first line of input contains an integer T, denoting the number of test cases.
    For each test case, the first line contains two integers N and M, denoting the number of vertexes and edges in the graph. (2 <= N <= 15, 0 <= M <= 1000)
    Next M lines, each line contains three integers X, Y and C, there is an edge from X to Y and the capacity of it is C. (1 <= X, Y <= N, 1 <= C <= 1000)

    Output:

    For each test cases, you should output the maximum flow from source 1 to sink N.

    Sample Input:

    2
    3 2
    1 2 1
    2 3 1
    3 3
    1 2 1
    2 3 1
    1 3 1

    Sample Output:

    Case 1: 1
    Case 2: 2

    题目链接

    裸网络流最大流模板题。
    网络流基础知识及最大流求解思路:

    数据结构与算法分析 - 网络流入门(Network Flow)

    最大流求解Ford-Fulkerson算法详解:

    7. 网络流算法–Ford-Fulkerson方法及其多种实现

    AC代码:

    1. // Ford-Fulkerson算法
    2. #include <bits/stdc++.h>
    3. using namespace std;
    4. #define mem(a,b) memset(a,b,sizeof(a))
    5. #define pb push_back
    6. #define mp make_pair
    7. typedef long long ll;
    8. typedef unsigned long long ull;
    9. typedef pair<int,int> P;
    10. const int INF = 0x3f3f3f3f;
    11. const int maxn = 20;
    12. const int mod = 1e9+7;
    13. const double eps = 1e-8;
    14. const double pi = asin(1.0)*2;
    15. const double e = 2.718281828459;
    16. void fre() {
    17. freopen("in.txt", "r", stdin);
    18. //freopen("out.txt", "w", stdout);
    19. }
    20. int t;
    21. int n, m;
    22. int x, y, c;
    23. // 起点、终点
    24. int st, en;
    25. // 增广路径流量
    26. int flow;
    27. // 最大流
    28. int ans;
    29. // 顶点标记数组
    30. bool vis[maxn];
    31. // 残留网
    32. int maze[maxn][maxn];
    33. // DFS寻找增广路径
    34. int dfs(int u, int FindFlow) {
    35. // 若找到汇点返回此增广路径中
    36. if (u == en) {
    37. return FindFlow;
    38. }
    39. // 若访问过此顶点则返回
    40. if (vis[u]) {
    41. return 0;
    42. }
    43. // 标记此顶点为已访问顶点
    44. vis[u] = 1;
    45. // 枚举寻找下一个顶点
    46. for (int i = 1; i <= n; ++i) {
    47. // 跳过两顶点之间容量为0的顶点
    48. if (maze[u][i]) {
    49. // 从i点寻找路径,并返回路径流量
    50. int LastLineFlow = dfs(i, FindFlow < maze[u][i] ? FindFlow : maze[u][i]);
    51. // 跳过路径流量为0的点
    52. if (LastLineFlow == 0) {
    53. continue;
    54. }
    55. // 找到增广路径后更新残留网
    56. maze[u][i] -= LastLineFlow;
    57. maze[i][u] += LastLineFlow;
    58. // 返回此增广路径流量
    59. return LastLineFlow;
    60. }
    61. }
    62. // 若未找到增广路径则返回0
    63. return 0;
    64. }
    65. int main(){
    66. //fre();
    67. scanf("%d", &t);
    68. for (int Case = 1; Case <= t; ++Case) {
    69. mem(vis, 0);
    70. mem(maze, 0);
    71. scanf("%d%d", &n, &m);
    72. st = 1, en = n;
    73. while (m--) {
    74. scanf("%d%d%d", &x, &y, &c);
    75. // 这道题有重边所以写为+=,=会WA
    76. maze[x][y] += c;
    77. }
    78. ans = 0;
    79. // 不断寻找增广路径
    80. while (flow = dfs(st, INF)) {
    81. // 增加流量
    82. ans += flow;
    83. mem(vis, 0);
    84. }
    85. printf("Case %d: %d\n", Case, ans);
    86. }
    87. return 0;
    88. }

    AC代码:

    1. // Dinic算法
    2. #include <bits/stdc++.h>
    3. using namespace std;
    4. #define mem(a,b) memset(a,b,sizeof(a))
    5. #define pb push_back
    6. #define mp make_pair
    7. typedef long long ll;
    8. typedef unsigned long long ull;
    9. typedef pair<int,int> P;
    10. const int INF = 0x3f3f3f3f;
    11. const int maxn = 2e3;
    12. const int mod = 1e9+7;
    13. const double eps = 1e-8;
    14. const double pi = asin(1.0)*2;
    15. const double e = 2.718281828459;
    16. void fre() {
    17. freopen("in.txt", "r", stdin);
    18. //freopen("out.txt", "w", stdout);
    19. }
    20. int t;
    21. int n, m;
    22. // 最大流结果
    23. int ans;
    24. // 起点终点
    25. int st, en;
    26. // 残留网
    27. int c[maxn][maxn];
    28. // 分层图深度
    29. int depth[maxn];
    30. // bfs分层图
    31. int DinicBfs() {
    32. queue<int> que;
    33. mem(depth, -1);
    34. depth[st] = 0;
    35. que.push(st);
    36. while (!que.empty()) {
    37. int temp = que.front();
    38. que.pop();
    39. for (int i = 1; i <= n; ++i) {
    40. if (c[temp][i] && depth[i] < 0) {
    41. depth[i] = depth[temp] + 1;
    42. que.push(i);
    43. }
    44. }
    45. }
    46. if (depth[en] > 0) {
    47. return 1;
    48. }
    49. return 0;
    50. }
    51. // dfs寻找增广路径
    52. int DinicDfs(int point, int MaxFlow) {
    53. if (point == en) {
    54. return MaxFlow;
    55. }
    56. int FindFlow;
    57. for (int i = 1; i <= n; ++i) {
    58. if (c[point][i] && depth[i] == depth[point] + 1 && (FindFlow = DinicDfs(i, min(MaxFlow, c[point][i])))) {
    59. c[point][i] -= FindFlow;
    60. c[i][point] += FindFlow;
    61. return FindFlow;
    62. }
    63. }
    64. return 0;
    65. }
    66. int main(){
    67. //fre();
    68. scanf("%d", &t);
    69. for (int Case = 1; Case <= t; ++Case) {
    70. mem(c, 0);
    71. scanf("%d%d", &n, &m);
    72. st = 1, en = n;
    73. int input_u, input_v, input_c;
    74. while (m--) {
    75. scanf("%d%d%d", &input_u, &input_v, &input_c);
    76. // 有重边所以一定要用"+="
    77. c[input_u][input_v] += input_c;
    78. }
    79. // Dinic主过程
    80. ans = 0;
    81. while (DinicBfs()) {
    82. ans += DinicDfs(st, INF);
    83. }
    84. // 输出结果
    85. printf("Case %d: %d\n", Case, ans);
    86. }
    87. return 0;
    88. }
  • 相关阅读:
    热更新技术简易原理及技术推荐
    利用freesurfer6进行海马分割的环境配置和步骤,以及获取海马体积
    让我们写一个 Win32 文本编辑器吧 - 1. 简介
    智能生活从这里开始:数字孪生驱动的社区
    上海交通大学计算机考研资料汇总
    新相微在科创板过会:计划募资约15亿元,2022年业绩开始下滑
    美国市场三星手机超苹果 中国第一属华为
    Pytorch实用教程:多分类任务中使用的交叉熵损失函数nn.CrossEntropyLoss
    Redis数据序列化器
    C++入门(4):auto、范围for、nullptr
  • 原文地址:https://blog.csdn.net/eeeeety6208/article/details/127853588