網路流之最大流Dinic --- poj 1459

来源:https://www.cnblogs.com/chen9510/archive/2019/05/10/10846876.html
-Advertisement-
Play Games

題目鏈接 Description A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be sup ...


題目鏈接

 

Description

A power network consists of nodes (power stations, consumers and dispatchers) connected by power transport lines. A node u may be supplied with an amount s(u) >= 0 of power, may produce an amount 0 <= p(u) <= pmax(u) of power, may consume an amount 0 <= c(u) <= min(s(u),cmax(u)) of power, and may deliver an amount d(u)=s(u)+p(u)-c(u) of power. The following restrictions apply: c(u)=0 for any power station, p(u)=0 for any consumer, and p(u)=c(u)=0 for any dispatcher. There is at most one power transport line (u,v) from a node u to a node v in the net; it transports an amount 0 <= l(u,v) <= lmax(u,v) of power delivered by u to v. Let Con=Σuc(u) be the power consumed in the net. The problem is to compute the maximum value of Con. An example is in figure 1. The label x/y of power station u shows that p(u)=x and pmax(u)=y. The label x/y of consumer u shows that c(u)=x and cmax(u)=y. The label x/y of power transport line (u,v) shows that l(u,v)=x and lmax(u,v)=y. The power consumed is Con=6. Notice that there are other possible states of the network but the value of Con cannot exceed 6.

Input

There are several data sets in the input. Each data set encodes a power network. It starts with four integers: 0 <= n <= 100 (nodes), 0 <= np <= n (power stations), 0 <= nc <= n (consumers), and 0 <= m <= n^2 (power transport lines). Follow m data triplets (u,v)z, where u and v are node identifiers (starting from 0) and 0 <= z <= 1000 is the value of lmax(u,v). Follow np doublets (u)z, where u is the identifier of a power station and 0 <= z <= 10000 is the value of pmax(u). The data set ends with nc doublets (u)z, where u is the identifier of a consumer and 0 <= z <= 10000 is the value of cmax(u). All input numbers are integers. Except the (u,v)z triplets and the (u)z doublets, which do not contain white spaces, white spaces can occur freely in input. Input data terminate with an end of file and are correct.

Output

For each data set from the input, the program prints on the standard output the maximum amount of power that can be consumed in the corresponding network. Each result has an integral value and is printed from the beginning of a separate line.

Sample Input

2 1 1 2 (0,1)20 (1,0)10 (0)15 (1)20
7 2 3 13 (0,0)1 (0,1)2 (0,2)5 (1,0)1 (1,2)8 (2,3)1 (2,4)7
         (3,5)2 (3,6)5 (4,2)7 (4,3)5 (4,5)1 (6,0)5
         (0)5 (1)2 (3)2 (4)1 (5)4

Sample Output

15
6
題意:由n個點構成的圖,其中np個點為發電站最大發電量為zi,nc個點為用戶最大消耗電量為zj,剩餘點為中轉點不產電也不消耗電,求此電網最大消耗電量?   思路:可將np個發電站看做源點,nc個用戶點看做匯點,為了構成單源單匯點,增加一個源點0連向np個發電站,其邊權為發電站的最大發電量;增加一個匯點n+1,由所有的用戶連向匯點n+1,其邊權為用戶的最大消耗電量。此時,就變成了單純的最大流問題。   註:第一次寫Dinic最大流代碼,簡單介紹一下Dinic演算法:   EK(EdmondsKarp)最大流的思想為,每次採用bfs搜索找到一條增廣路(設流量為flow),改變這條路徑上的所有的邊權值都減少flow,同時這條路徑上的所有反向邊權值增加flow,重覆直至找不到增廣路為止。   Dinic演算法很明顯是EK的一個優化演算法,其先採用 bfs 將圖按深度分層,然後 dfs 找到所有的增廣路並同樣改變所有的邊權值以及反向邊的權值,很明顯這樣dfs貪心的找到所有的增廣路並不是最優解,故迴圈再用bfs重新分層,dfs找增廣路,直到bfs分層沒有路徑能走到匯點,此時即是最大流量了。   最大流Dinic代碼如下:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
using namespace std;
const int N = 105;
const int MAXN = 1e9 + 7;

struct Edge {
    int to;
    int value;
    int next;
}e[2*N*N];
int head[N], cnt;
int deep[N];
int n, np, nc, m;

void insert(int u, int v, int value) {
    e[++cnt].to = v;
    e[cnt].value = value;
    e[cnt].next = head[u];
    head[u] = cnt;
}

void init() {
    memset(head, -1, sizeof(head));
    cnt = -1;
}

bool BFS() {
    memset(deep,-1,sizeof(deep));
    queue<int> Q;
    deep[0] = 0;
    Q.push(0);
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();
        for (int edge = head[u]; edge != -1; edge = e[edge].next) {
            int v = e[edge].to;
            if (deep[v] == -1 && e[edge].value > 0) {
                deep[v] = deep[u] + 1;
                Q.push(v);
            }
        }
    }
    if (deep[n + 1] == -1) return false;
    return true;
}

int DFS(int u,int flow_pre) {
    if (u == n + 1) return flow_pre;
    int flow = 0;
    for (int edge = head[u]; edge != -1; edge = e[edge].next) {
        int v = e[edge].to;
        if (deep[v] != deep[u]+1 || e[edge].value==0) continue;
        int _flow= DFS(v, min(flow_pre, e[edge].value));
        flow_pre -= _flow;
        flow += _flow;
        e[edge].value -= _flow;
        e[edge ^ 1].value += _flow;
        if (flow_pre == 0) break;
    }
    if (flow == 0) deep[u] = -1;
    return flow;
}
int GetMaxFlow() {
    int ans = 0;
    while (BFS()) {
        ans += DFS(0,MAXN);
    }
    return ans;
}
int main()
{
    while (scanf("%d%d%d%d", &n, &np, &nc, &m) != EOF) {
        init();
        int u, v, z;
        for (int i = 0; i < m; i++) {
            scanf(" (%d,%d)%d", &u, &v, &z);
            insert(u+1, v+1, z);
            insert(v+1, u+1, 0);
        }
        for (int i = 0; i < np; i++) {
            scanf(" (%d)%d", &u, &z);
            insert(0, u+1, z);
            insert(u+1, 0, 0);
        }
        for (int i = 0; i < nc; i++) {
            scanf(" (%d)%d", &u, &z);
            insert(u + 1, n + 1, z);
            insert(n + 1, u + 1, 0);
        }
        printf("%d\n",GetMaxFlow());
    }
}

 

 
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 大家好,忙裡抽空更新一下自己的博客,算是自己的一個進步,C語言視頻啟蒙我早就看完啦,只是覺得這個視頻真不錯,所以給大家分享一下,同時自己還有很多沒有理解透徹,寫寫博客算是一個筆記更是對自己所學的知識的吸收,廢話不多直接開始今天的主題,"C語言的選擇結構" 關係運算符 小於:< 大於:> 等於:= = ...
  • 描述Object wait()/notify()跟Condition await()/signal()的基本用法,三連問:解釋為什麼wait() 要放在while裡面?為什麼wait()方法放在Object對象中?為什麼wait()必須在同步方法/代碼塊中調用?以及這兩種通知/等待機制的區別 ...
  • 昨天組內同學在使用php父子進程模式的時候遇到了一個比較詭異的問題 簡單說來就是:因為fork,父子進程共用了一個redis連接、然後父子進程在發送了各自的redis請求分別獲取到了對方的響應體。 復現示例代碼: testFork.php PowerSpawn.php 主要用戶進程fork管理工作 ...
  • 1. HTML 定義 BS 模式:Browser、Server,即瀏覽器與伺服器模式。 HTML(Htyper Markup Language)即超文本標記語言,超文本(頁面內可以包含圖片、鏈接、引用、甚至程式 ),標記語言:標記(標簽)構成的語言。 網頁 網頁即 HTML文檔,由瀏覽器解析並展示出 ...
  • 學習PyQuery庫 好了,又是學習的時光啦,今天學習pyquery 來進行網頁解析 常規導入模塊(PyQuery庫中的pyquery類) from pyquery import PyQuery as pq 通常使用url初始化 doc = pq(url='http://www.baidu.com' ...
  • RabbitMQ是一個在AMQP基礎上完整的,可復用的企業消息系統。他遵循Mozilla Public License開源協議。 MQ全稱為Message Queue, 消息隊列(MQ)是一種應用程式對應用程式的通信方法。應用程式通過讀寫出入隊列的消息(針對應用程式的數據)來通信,而無需專用連接來鏈 ...
  • 這一篇我們來看看紅黑樹,首先說一下我啃紅黑樹的一點想法,剛開始的時候比較蒙,what?這到底是什麼鬼啊?還有這種操作?有好久的時間我都緩不過來,直到我玩了兩把王者之後回頭一看,好像有點兒意思,所以有的時候碰到一個問題困擾了很久可以先讓自己的頭腦放鬆一下,哈哈! 不瞎扯咳,開始今天的正題; 前提:看紅 ...
  • 在實際開發中經常遇到時間格式的轉換,例如: 前端傳遞的時間格式是字元串格式,我們需要將其轉換為時間戳,或者前臺傳遞的時間格式和我們資料庫中的格式不對應,我們需要對其進行轉換才能與資料庫的時間進行匹配等。 1、將字元串時間轉換成時間戳 將字元串時間轉換成時間組後在將其轉換成時間戳格式 得到時間組對象後 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...