最小コスト[POJ - 2516] [ネットワーク]最小コストの最大流量

トピックリンク

質問の意味

  彼らは商品を調達する必要がある事業、商品のサプライヤーのNの数、ならびに項目を必要とする企業のM、N Kの種類があり、各項目は、対応する要求を有し、M企業は、各アイテムの在庫を対応され、その後でK N * Mの行列は、ビジネスユニットへの供給業者からKの物品搬送の価格を表し、それが最小コストの標準最大流量である、我々はすべてのサプライヤーとソースのために、そのような側面を作成する必要がありますストリームのサイズを確立するためのポイントはサイドが所有する数であり、インフィニティエッジ及び単価の側面を確立するためのビジネスマンは、ストリームの価格です、そして、そのニーズの大きさを確立するためのミーティングポイントに到達するために、ビジネス側の流れから始まり、ミーティングポイントソース側を確立するためのコストは0です。

アイデア

  最初は、私が直接費用流を実行する予定が、この実行後、あなたがそれを完了するために再度指示したいならば、Nは、考慮ビジネスのニーズだけでなく、M・プロバイダーが取っている、ポイントTを見つけるだろう議論するためにK回に分けた場合の数があまりにも多く、このような点を(N + M + N * K + M * K)の数であるが、我々はそれを変更することができ、時間の複雑さをダウン最適化することはできません。

  そこで、次のように商品の種類及び建設側のコストに対応する各プロセスは、ストリームを実行し、K回に分けます。

 

#include <iostreamの> 
する#include <cstdioを> 
する#include <cmath> 
の#include < ストリング > 
の#include <CStringの> 
する#include <アルゴリズム> 
の#include <限界> 
の#include <ベクトル> 
の#include <スタック> 
の#include <キュー> 
#include < セット > 
の#include <地図>
 の#define lowbit(X)(X&( - X))
 の#define PI 3.141592653589793
 の#define E 2.718281828459045
 の#define INF 0x3f3f3f3f
 の#define半分(L + R)>>
1つの#defineLSNのRT << 1
 の#define RSN RT << 1 | 1
 の#define LSONのLSN、L、ミッド
 の#define RsonのRSN、ミッド+ 1、R用
 の#define QL LSON、QL、QR
 の#define QR Rson、QL、QR
 の#define私自身、室温、L、R
 使って 名前空間はstdを、
const  int型 MAXN = 107、S = 0 ;
整数 N、M、K、T、必要[ 55 ]いる[ 55 ]、ショップ[ 55 ] [ 55 ]、優れた[ 55 ] [ 55 ]、R [MAXN] [MAXN]、[MAXN] [MAXN] C ;
INT プレ[MAXN]、DIST [MAXN]、フロー[MAXN]、ANS。
キュー < 整数 > Q;
BOOL inque [MAXN]。
ブールspfa()
{ 
    memsetの(前、0はsizeof(PRE))。memset(DIST、INF、はsizeof(DIST))。memsetの(inque、はsizeof (inque)); 
    Q.push(S)。inque [S] = DIST [S] = 0 ; フロー[S] = INF。
    しばらく(!Q.empty())
    { 
        int型のu = Q.front(); inque [U] = Q.pop();
        以下のためにint型 I = 0 I <= T;;私は++
        {
            もし(R [U] [I] && DIST [I]> DIST [U] + C [U] [I])
            { 
                DIST [I] = DIST [U] + C [U] [I]。
                フロー[I] = 分(フロー[U]、R [U] [I])。
                事前[I] = U。
                もし(!inque [I])
                { 
                    inque [I] = 
                    Q.push(I); 
                } 
            } 
        } 
    } 
    戻りプレ[T]を。
} 
INT EK()
{ 
    int型 ANS = 0;
    一方、(spfa())
    { 
        int型今= T、ラス= プレ[今]。
        一方、(今)
        { 
            R [ラス] [今] - = 流量[T]。
            R [今] [ラス] + = 流量[T]。 = ラス。
            ラス = あらかじめ[今]。
        } 
        ANS + =流量[T] * DIST [T]。
    } 
    戻りANS。
} 
インラインボイドのinit()
{ 
    ANS = 0T = N + M + 1 
    のmemset(必要、0sizeof (ニーズ)); 
    memsetを(有し0はsizeofを)(ました)。
} 
int型のmain()
{ 
    一方(scanf関数(" %D%D%D "、&​​N、&M、&K)&&(N || M || K))
    { 
        INIT()。
        int型 iは= 1 ; iが<= N; iが++ 
        { 
            ためINT J = 1 ; J <= K; J ++ 
            { 
                scanf関数(" %のD "、およびショップ[I] [J ];買物[I] [J])。
                必要[J] + =
            } 
        } 
        のためにint型 I = 1 ; I <= M; iは++ 
        { 
            ためのint型 J = 1 ; J <= K; J ++ 
            { 
                scanf関数(" %のD "、および良好な[I] [J])。
                持っている[J] + = 良い[I] [J]。
            } 
        } 
        ブールフラグ= 以下のためにint型 i = 1 ; iが<= Kを、iは++ 
        { 
            場合(必要[I]> いる[i])と
            { 
                フラグ = 破ります; 
            } 
        } 
        のためのint型 i = 1 ; iが= Kを<Iは++ 
        { 
            memsetの(R、0はsizeof (登録商標)); 
            memset(C、0はsizeof (c)参照)。
            INT J = 1 ; J <= N; J ++ 
            { 
                R [S] [J] = ショップ[J] [I];
                以下のためのint型 KK =1 ; KK <= M。KK ++ 
                { 
                    scanf関数(" %のD "、&​​C [J] [N + KK])。
                    C [N + KK] [J] = -c [J] [N + (株)]。
                    R [J] [N + KK] = INF。
                } 
            } 
            場合(フラグが!)続けますINT J = 1 ; J <= M; J ++)R [N + J] [T]は= 良い[j]を[I]。
            ANS + = EK()。
        } 
        もし(!フラグ){のprintf(" -1の\ n ");続け; } 
        のprintf(" %d個の\ n " 、ANS)。
    } 
    戻り 0 
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/WuliWuliiii/p/10945276.html