ゴーイング・ホームPOJ-2195(最小コスト最大フローテンプレート)

トピックリンク:POJ-2195は、ゴーイング・ホーム

問題の意味

与えられた$ N $ $ M $は、列線グリッドは、「M」 'はHが家を示し、人を表しており、同じ数の「M」と「H」は、人は家、家を入力することができますあなただけの1水平方向と垂直方向の両方乗り出す、と今、誰もが家を入力すること、人、および最短経路に行くことができます。


考え

これは、最小の重みマッチング問題を有する二部グラフは、最小コスト、最大流量を直接解決することが可能です。

1の全てであっても、容量、コスト面0各家に一人一人の人々にソースが1の容量も1の容量をシンクするために、各家のコストエッジまでの距離を接続され、コストが0側であります最小コスト最大流量に走りました。


コードの実装

書式#include <iostreamの> 
の#include <cstdioを> 
する#include <ベクトル> 
の#include <キュー> 
の#include <cstdlib> 
書式#include <CStringの>
 に#define N 5000
 使って 名前空間はstdを、
typedefのペア < int型int型 > P;
const  int型 INF = 0x3f3f3f3f 構造体のエッジ
{ 
    int型、キャップ、コスト、REVに、
    エッジ(INT T、INT C、INT CC、INT  R)(t)は、キャップ(C)に、コスト(CC)、REV(R){}
}; 
int型V。 
ベクトル <エッジ> G [N]。
int型H [N]。
INTのDIST [N]。
INT prevv [N]。
int型preve [N]。

ボイド addedge(INT  からINTに、int型のキャップ、int型のコスト)
{ 
    [G から.push_back](エッジ(に、キャップ、コスト、[する] G .size()))。
    .push_back【に】G((エッジから0 [G、-COST、から).size(] - 1 ))。
} 
INT min_cost_flow(INT S、int型T)
{ 
    int型 RES =0 ; 
    フィル(H、H + V、0 );
    一方、
    { 
        PRIORITY_QUEUE <P、ベクトル<P>、大きな<P>> Q。
        フィル(DIST、DIST + V、INF)。
        DIST [S] = 0 ; 
        q.push(P(0 、S))。
        一方、(!q.empty())
        { 
            P、P = q.top()。q.pop();
            int型の V = p.second。
            もし(DIST [V] <p.first)続けますにとってint型 I = 0 ; iが++; iが[V] .size()Gを< 
            { 
                エッジ&E = [I] G [V]。
                もし(e.cap> 0 && DIST [e.to]> DIST [V] e.cost + H + [V] - H [e.to])
                { 
                    DIST [e.to] = DIST [V] + E .cost + H [V] - H [e.to]。
                    prevv [e.to] = V。
                    preve [e.to] = I。
                    q.push(P(DIST [e.to]、e.to))。
                } 
            } 
        } 
        もし(DIST [T] == INF)休憩INT J = 0 ; J <V、J ++ 
            H [J] + = DIST [J]。
        int型 D = INF。
        INT ; X = Sで!X = X = T prevv [X])
            D = 分(D、G [prevv [X]] [preve [X]]キャップ。)。
        もし(dは== 0ブレーク
        RES + =のD *の時間[T]。
        INT ; X = Sであり、X = T!X = prevv [X])
        { 
            エッジ&E =){ G [prevv [X]] [preve [X]]。
            e.cap - = D; 
            G [X] [e.rev]の.cap + = D。
        } 
    } 
    戻りRES。
} 

int型のmain()
{ 
    int型、N M。
    一方、(〜のscanf(" %D%dの"、&​​N、&M)&& N && M){ 
        ベクトル <P> HOU、人;
        char型のCH;
        int型 iは= 0 ; iがN <I ++は{)
             のためにINT J = 0 ; J <M、J ++
                scanf関数(" %のC "、&CH);
                もし(CH == ' H ' )hou.push_back(make_pair(I、J));
                それ以外の 場合は(CH == ' M ' )man.push_back(make_pair(I、J)); 
            } 
        } 
        int型の CNT = hou.size()。
        V = 2 * CNT + 2 INT S = 2 * CNT、T = 2 * CNT + 1 以下のためのint型 I = 0 ; iはVを<+10 ; I ++ )G [i]が.clear();
        以下のためにint型 i = 0 ; iはCNT <I ++は{)
             のためのint型 J = 0 ; J <CNT; J ++ ){ 
                addedge(I、CNT + J、1、ABS(男[I] 1次回- HOU [J ] 1次回)+ ABS(男性[I] .second - HOU [J] .second))。
            } 
        } 
        のためにint型 i = 0 ; iは、CNTを<; iは++ ){ 
            addedgeを(S、I、10 ); 
            addedge(CNT + I、T、10 ); 
        } 
        のprintf(" %d個の\ n " 、min_cost_flow(S、T))。
    } 
    戻り 0 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/kangkang-/p/11324602.html