火星探査の質問(最大コスト最大フロー)

火星探査の質問(luogu)

解決

コストの流れを考えるのは簡単

問題に右の点を解決するためには、障害物のない私は2つのポイントに分けポイントは、双方向の愛

AIから側(これらの非生産的で表現)0のコストで正の無限大(示さ無制限パス)のBIも流れに

(を通じて一度だけ示される)1の点は、I石であれば、再びAIからBIにも流量1の費用で(これは1を通じて収益を表す)エッジ

ポイントは、私がjを指すことができますし、i、jは、BI AJからも、正の無限大の流れ、ゼロコストの側に、障害物でない場合

A1は0エッジのコストで車両の数を検出するためにも開始点から流出します

BNからも0エッジのコストでプローブ車両の数とトラフィックの終わりまで

最大のコストの最大フローを実行します

コード

 

書式#include <cstdioを> 
する#include <cstdlib> 
書式#include <キュー> 
の#include <CStringの> 
の#include <アルゴリズム>
 使用して 名前空間をSTD。
CONST  INT N = 3E3、M = 1E5。
int型のプレ[N]、S、T、車、D [N]、N、M、INCF [N]、[ 40 ] [ 40 ]、INF = 1 << 30 、DIS [N]。
INTヘッド[N]、NXT [M]、版[M]、エッジ[M]、コスト[M]、TOT = 1 、maxflow、maxcost。
BOOL  [N]。
INTの ID(int型のx、int型のy、int型INV)
{
    戻り(X- 1)* M + Y + INV * N * M。
} 
ボイド追加(INT U、INT V、INT、W INT C)
{ 
    版[ ++ TOT = V、NXT [TOT =頭部[U]、エッジ[TOT =コスト[TOT = C、W、ヘッド[U] = TOT。
    版【 ++ TOT = U、NXT [TOT =頭部[V]、エッジ[TOT = 0、コスト[TOT] = - C、頭[V] = TOT。
} 
ブールspfa()
{ 
    memsetの(DIS、0x80をはsizeof (DIS))。
    memsetの(前、0はsizeof (PRE))。
    int型最後=  DIS [S]。
    キュー < 整数 > Q; 
    DIS [S] = 0、q.push(S)、INCF [S] = 1 << 30 しばらく(!q.empty())
    { 
        int型のu = q.front(); 
        q.pop(); 
         [U] = 以下のためにINT iがヘッド[U]、Vが=; I;私は= NXT [I])の
             場合(エッジ[I]> 0 && DIS [V =版[I] <DIS [U] + コスト[i])と
            { 
                DIS [V] = DIS [U] + コスト[i]は、
                INCF [V] =分(エッジ[I]、INCF [U])。
                事前[V] = I。
                もし(! [V]) [V] = 、q.push(V); 
            } 
    } 
    を返す DIS [t]を=!最後。
} 
ボイド更新()
{ 
    maxflow + = INCF [T]、maxcost + = INCF [T] * DIS [T]。
    int型のx = T;
    一方、(!X = S)
    { 
        int型 I = プレ[X]。
        エッジ[I] - = INCF [T]、エッジ[I ^ 1 ] + = INCF [T]。
        X =版[I ^ 1 ]。
    }
} 
ボイド DFS(int型のx、int型のy、int型の POS、INT K)
{ 
    int型KX、KY、MOV。
    以下のためにINT iが[POS]ヘッド=; I;私は= NXT [I])
    { 
        int型 V = 版[I]を、
        もし(V == S || V == T || V == POS-N * M ||エッジ[I ^ 1 ] <= 0続けます
        エッジ[I ^ 1 ] - もし(V> N * M)
        { 
            DFS(X、Y、V、K)。
            リターン; 
        }
        もし(V ==(X- 1)* M + Y + 1)KX = X、KY = Y + 1、MOV = 1  KX = X + 1、KY = Y、MOV = 0 
        printf(" %D%D \ n " 、K、MOV)。
        DFS(KX、KY、V + N * M、K)。
        リターン; 
    } 
} 
int型のmain()
{ 
    scanf関数(" %D%D%D "、&車、&​​M、&N)
    S = 0、T = N * M * 2 + 1 以下のためのint型 I = 1 ; I <= N; I ++ のためのINT J = 1 ; J <= Mであり、j ++ 
            のscanf(" %dの"、および[I] [J])。
    もし([n]は[M] == 1 || [ 1 ] [ 1 ] == 1戻り 0 ;
    以下のためにINT iが= 1 ; iが<= N; I ++ のためのINT J = 1 ; J <= Mであり、j ++ 
        { 
            場合([I] [J] == 1続行します; 
            追加(ID(I、J、0)、ID(I、J、1)、INF、0 );
            もし([I] [J] == 2)を追加(ID(I、J、0)、ID(I、J、1)、11 )。
            もし(I <N && [I + 1 ] [J] =!1)(ID(I、J、追加1)、ID(I + 1、J、0)、INF、0 );
            もし(J <M && [I]、[J + 1 ]!= 1)を追加(ID(I、J、1)、ID(I、J + 10)、INF、0); 
        } 
    、(S、ID(追加110)、車、0)、追加(ID(N、M、1)、T、車、0 );
    一方、(spfa())更新();
    以下のためにINT iが= 1 ; I <= maxflow I ++ 
        DFS(111 、I)。
    リターン 0 ; 
}

 

 

 

おすすめ

転載: www.cnblogs.com/hsez-cyx/p/12407511.html