HDU-1532 Drainage Ditches (最大流E-K算法)

題目大意:

有一個農田,爲了排水,約翰挖了m條排水溝聯通各個節點,問最大水流量是多少。


算法分析:

我之前做一道要用到最大流,於是我去學習最大流算法的解法,看了n篇博客,最後還是看得一知半解,結果最後還是硬生生將模板背了下來,但是不知道爲什麼要這樣做,以後有空再研究研究。
最大流問題的關鍵是尋找增廣路,E-K算法是用隊列的方式是查詢增廣路,然後去增廣路上的最小流量,然後每條路徑都加上最小流量,對稱路徑減去最小流量。我花了一些時間,終於將這道題A出來了,最關鍵的是,這道題會有重邊,而且你還不能取最大值,而是累加重邊的權值(真是日了狗)。


代碼實現:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <iostream>
#include <algorithm>

using namespace std;

struct node
{
    int from;
    int to;
    int flow;
    int cap;
    bool in;
} edge[220][220];

int m, n;
int add[220];
int pre[220];
int Q[220];
bool statu[220];            // 標記當前結點是否已經進入隊列

int main()
{
    int x, y, z;

    while (scanf("%d%d", &m, &n) != EOF) {
        int maxn = 0;
        memset(edge, 0, sizeof(edge));
        for (int i = 1; i <= m; i++) {
            scanf("%d%d%d", &x, &y, &z);
            edge[x][y].cap += z;
            edge[x][y].in = edge[y][x].in = true;
        }
        bool flag = true;

        while (flag) {
            int front_, rear_;
            front_ = rear_ = 1;
            flag = false;
            memset(statu, 0, sizeof(statu));
            pre[1] = 0;
            Q[1] = 1;
            add[1] = 1 << 30;
            while (front_ <= rear_ && !flag) {
                int index = Q[front_++];           // 取出隊首元素
                for (int i = 1; i <= n; i++) {
                    if (edge[index][i].in && !statu[i] && edge[index][i].cap > edge[index][i].flow && i != pre[index]) {
                        add[i] = min(add[index], edge[index][i].cap-edge[index][i].flow);
                        statu[i] = true;
                        pre[i] = index;
                        Q[++rear_] = i;             // 入隊列
                        if (i == n) {
                            flag = true;
                            break;
                        }
                    }
                }
            }
            if (!flag) {
                break;          // 防止反覆加
            }
            for (int i = n; i != 1; i = pre[i]) {
                edge[pre[i]][i].flow += add[n];
                edge[i][pre[i]].flow -= add[n];
            }
            maxn += add[n];
        }
        printf("%d\n", maxn);
    }

    return 0;
}


發佈了53 篇原創文章 · 獲贊 7 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章