ダイクストラの最小コスト最大フロー問題

           最小費用流問題について、その焦点は、パスを増強されたもの「増補道」にありますか?道路の結果を作るために、よりを追加する方法に加えて、道路を見つけるための基礎があり、最短経路を見つける道の残りの真ん中を見つけるために最小の方法を継続して使用することができ、道路ダイクストラの直接使用、したがって、これは我々が必要結果ではない> 5-> 4-> 6秒1-> 2-> 6 - > 3 - が、2本の道路が互いに必ずしも最初に全体的な最小道路1ない来ます第二の最短経路を探していたとき、私たちがすることはできません、戻って行くことができるようにする必要があります

初めて抗エッジプラスかなりの数を減らすために正の辺の数を取って初めて、マップを構築する時に戻ってする方法> 5 3-、プラスカウンターエッジを行っていないので、あなたは、第二の5員環を取ることができるように> 3次いで3-> 6本ライン、最初のパス3-> 5、第スクレープ5->かなりの最初のパスを移動し、道路が可能な最小を取ることができるように、バック3に行きます。

書式#include <iostreamの> 
の#include <CStringの> 
の#include <キュー> 
std名前空間を使用しました。
/ * 6 11 1 2 23 1 3 12 1 4 99 2 5 17 2 6 73 3 5 3 3 6 21 4 6 8 5 2 33 5 4 5 6 5 20 * / 
の#define MAX 23060 
int型MinCos。
int型V、CNT。
int型ヘッド[MAX]; 
[MAX]次にINT。
int型F [MAX]; //流量
[MAX]へのint; //终结的に
int型ディス[MAX]; 
int型のCos [MAX]; //花费
int型VIS [MAX]; 
ボイド_ADD(INT、INT Bを、int型のF、INT c)は
{ 
    CNT ++。
    F [CNT] = F。
    [CNT] = Bへ; 
    COS [CNT = Cを、
    次の[CNT] =ヘッド[A]。
    [A] = CNTヘッド。
} 
無効アドオン(、int型のB int型、int型C)//增加点用于构图 
{
    IF(VIS [A] && = 1 && = V!!)
    { 
        _ADD(+ V、1,0)。
        _ADD(A + V、0,0)。
        VIS [A] = 1。
    } 
    (VIS [B] && B = 1 && B = V!!)なら
    、{ 
        _ADD(B、B + V、1,0)。
        _ADD(B + V、B、0,0)。
        VIS [B] = 1。
    } 
    IF(== 1件の|| B == V)
    { 
        IF(= 1 && B == V!)
        { 
            _ADD(A + V、B、1、C)。
            _ADD(B、A + V、0、-c)。
        }そうであれば(== 1件の&& B = V!)
        { 
            _ADD(A、B、1、C)。
            _ADD(B、0、-c)。
        } 
        { 
            _ADD(A、B、1、C)。
            _ADD(B、0、-c)。
        } 
    }そうでなければ(== V || B == 1){}もし
    { 
        _ADD(A + V、B、1、C)。
        _ADD(B、A + V、0、-c)。
    } 
} 
ボイドDijks(INT folw)// Dijks求最小费用最大流算法
{ 
    PRIORITY_QUEUE <ペア<整数、整数>、ベクトル<ペア<整数、整数>>、大きな<ペア<整数、整数>>> SP。
    int型H [MAX]。
    [MAX-1]〜= 1。
    memsetの(H、0、はsizeof(H))。
    (folw> 0){一方
        のmemset(DIS、0x3f3f3f3f、はsizeof(DIS))。
        memsetの(VIS、0、はsizeof(VIS))。
        DIS [1] = 0。
        ペア<int型、int型> T; 
        sp.push(make_pair(0、MAX-1))。
        INT [MAX]の事前。
        [1] = 0の事前。
        しばらく(!sp.empty()){
            T = sp.top()。
            sp.pop();
            ;へ= [t.second]にINT 
            もし(Vを==に)続けます。
            (VIS [する])続ける場合。
            もし(DIS [に対して<t.first)続ける; //剪枝
            VIS = 1 []。
            {(!; I = -1次のI = [I] int型I =ヘッド[に対して])のための
                時間- (F [i]が&&ディス>ディス[I]へ] + [へ] H [する]であれば+コス[I]){//跟新最小费用[I] [へ] 
                    ディス+ H [に対する] =ディス[I]へ] [へ] - +コス[I] [I]へ] H。
                    [I] = t.secondを事前; //记录上一个节点
                    ([I] == Vまで)場合
                    { 
                        [MAX-2]を事前= I。
                    } 
                    sp.push(make_pair(DIS [に[I]、I))。
                }
            } 
        } 
        IF(DIS [V] == 0x3f3f3f3f)BREAK; 
        のための(INT I = 1; I = 2 * V <; Iは++){ 
            H [I] + =ディス[I]; //私は理解していないけれどもブログ記事書き込み特に
        } 
        ため(INT I =事前[MAX-2]; I = MAX-1 ;! I =プレ[I]が。)を見つける//最小コスト
        { 
            MinCos + =コス[I]; 
            F. [I] - = 1;格納されたデータ、偶数番目のメモリの前縁、奇数の逆側の0 //スタート
            F [I ^ 1] + = 1; // I ^ 1が奇数である
        } 
        Folw - = 1; 
    } 
    COUT << << MinCos "\ N-"; 
} 
int型のmain()
{ 
    (偽の)IOSの:: sync_with_stdio; 
    cin.tie(0); 
    int型のP、
    一方(V >> P CIN){ 
        ため(INT I = 0。私は20060 <; Iは++)
        { 
            F. [I] = 0;
            [I] = 0であり; 
            DIS [I] = 0; 
            COS [I] = 0; 
            VIS [I] = 0; 
            ヘッド[I] = - 1。
            次の[I] = - 1。
        } 
        MinCos = 0。
        CNT = -1; 
        {ため(; iは、P <I ++はI = 0 INT)
            、B、Cのint型。
            CIN >> A >> B >> C。
            (A、B、C)を加えます。
        } 
        Dijks(2)。
    } 
    0を返します。
}

 ブログhttp://www.cppblog.com/guojingjia2006/archive/2009/11/12/57905.html H [i]の機能を説明するための兄

おすすめ

転載: www.cnblogs.com/hycn/p/11329955.html