Poj1459電力ネットワークは、事前の流れを促進します

Poj1459電力ネットワークは、事前の流れを促進します

問題の説明:

電力ネットワークは、ノード(発電所、消費者とで構成され
、電力輸送ラインによって接続ディスパッチャ)。ノードuをすることができる
量s(U)> =電力の0、量を生成することが0に付属
<= P(U)<= Pの
最大値(U)パワーの、量0 <= cを消費することができる(U )<=分(S(U)のC
MAX(U))の電力、及び量送達することができる
(U)= sの(U)+ P(U)-C(U)パワーのdは。C(U)= 0:以下の制限が適用され
、任意の消費者のための任意の発電所、P(U)= 0のため、および任意のためのP(U)= Cの(U)= 0
ディスパッチャ。あり、ほとんどの一つの電力輸送ラインでの(U、V)ノードのuから
ネット内のノードvへ。それは量0 <= Lを搬送する(u、v)は<= Lの
最大値(u、v)はVとUによって供給される電力。うコン=Σ
UC(U)ネットで消費される電力も。問題は、コンの最大値を計算することです。
IMG

例では、図1にuがP(U)= xおよびPのことを示している発電所のラベルX / Yである
maxが(u)はYを=。消費者のX / Yのラベルは、Uは、C(u)は、XとC =ことを示す
MAX(u)はYを=。電力搬送ライン(U、V)のラベルのx / yがL(U、V)= xおよびLのことを示している
MAX(u、v)はYを=。消費される電力は、コン= 6です。ていることに注意してください
そこにネットワークの他の可能な状態であるが、コンの値が
6を超えることはできません。

入力

入力で複数のデータセットがあります。各データセットは、電力網をコードします。0 <= N <= 100(ノード)、0 <= NP <= N(発電所)、0 <= NC <= N(消費者)、及び0 <= M <= N ^ 2:これは、4つの整数で始まり(電力輸送ライン)。m個のデータトリプレットに従う(u、v)はuおよびvは、(0から始まる)ノード識別子であり、Z、および0 <= Z <= 1000 L maxの値(U、V)。Uは発電所の識別子であり、0 <= Z <= 10000がP MAX(U)の値であるNPダブレット(U)Zが、従います。データセットは、NCダブレット(U)で終了uは消費者の識別子であり、0 Z、<= Z <= 10000のC max(U)の値です。すべての入力番号は整数です。(U、V)のZトリプレットと空白を含まない(U)Zダブレット、除き、空白は入力に自由に起こり得ます。

出力

入力からの各データセットのために、標準出力にプログラムプリント対応ネットワークで消費可能な電力の最大量。各結果は、整数値を有し、別の行の先頭から印刷されます。

サンプル入力

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

サンプル出力

15

6

分析:

この問題は、最大流量を解決するために、ネットワークの最大フローネットワークモデルは、ソースとシンクを必要と使用することができる、元の植物、ステーションスケジュールと消費者にできないソースノードとシンクとして、元の基礎そうN + 1、N + 2、ソースとシンク頂点番号を追加します。

(トリプレットのタイトルのために、ソースの導入後と、各プラントのソース点PMAXアークからの鉛の容量をシンク、各消費者から、シンクするアークのCmax能力を挙げU、V)Z。さえ頂点U Z容量アークから頂点vまで。シンクに流れる電流の各消費者の実際の消費量となるよう、電流源の最大量は、発電所及びPMAXのそれぞれに設けられています。

最大流量は、直下解決することができ、ここで使用される方法は、プレフロー推進です。

#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
using namespace std;
const int maxn = 110;
const int maxf = 0x7fffffff;
int n,np,nc,m;
int resi[maxn][maxn];
deque<int> act;
int h[maxn];
int ef[maxn];
int s,t,V;
void push_relabel() {
    int sum = 0;
    int u,v,p;
    for(int i = 1;i <= V;i++) h[i] = 0;
    h[s] = V;
    memset(ef,0,sizeof(ef));
    ef[s] = maxf;ef[t] = -maxf;
    act.push_front(s);
    while(!act.empty()) {
        u = act.back();
        act.pop_back();
        for(int i = 1;i <= V;i++) {
            v = i;
            if(resi[u][v] < ef[u]) p = resi[u][v];
            else p = ef[u];
            if(p > 0 && (u == s || h[u] == h[v] + 1)) {
                resi[u][v]-=p;resi[v][u]+=p;
                if(v == t) sum+=p;
                ef[u]-=p;ef[v]+=p;
                if(v != s && v != t) act.push_front(v);
            }
        }
        if(u != s && u != t && ef[u] > 0) {
            h[u]++;
            act.push_front(u);
        }
    } 
    printf("%d\n",sum);
}
int main() {
    int u,v,val;
    while(scanf("%d%d%d%d",&n,&np,&nc,&m) != EOF) {
        s = n + 1;t = n + 2;V =  n+2;
        memset(resi,0,sizeof(resi));
        for(int i = 0;i < m;i++) {
            while(getchar() != '(');
            scanf("%d,%d)%d",&u,&v,&val);
            resi[u+1][v+1] = val;
        }
        for(int i = 0;i < np;i++) {
            while(getchar() != '(');
            scanf("%d)%d",&u,&val);
            resi[s][u+1] = val;
        }    
        for(int i = 0;i < nc;i++) {
            while(getchar() != '(');
            scanf("%d)%d",&u,&val);
            resi[u+1][t] = val;
        }
        push_relabel();
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/pot-a-to/p/10959986.html