微分制約アルゴリズム----羅区P4878 [USACO05DEC]レイアウト

トピック:

 

 主な問題は、不平等のXI-XJ I、J 2頭の牛が、<= AKさん、XI-XJ距離番目mdの与えられたフォーマットミリリットル+意味を見ることは難しいことではありません、我々は最大値x1-XNを求めるべきであるが。

 

 

 

縦加速度およびいくつかの不等式に我々これらX1-XN <= A1 + A2 + A3 + A4 + ... + AK、 で減算我々が見ることができるプロセスdijstra図、この簡単な計算このプロセスは、正確に切断しない緩い動作を!

その後、我々は正の解を得る-主に処理するために使用される差分拘束アルゴリズム、差動拘束システム:システムは不等式mはAI-aj≤k形のを(形成された変数nおよびmの制約、で構成されている場合I、j∈[1、n]は 、kは差動拘束システムと呼ばれる定数)、です。

結論:差動拘束システム、グラフ理論に変換することができる単一始点最短経路(または最長経路)問題を解決します。

 

差動制約と最短モデルの関係

 

X [J] <= [K]、X [i]は<= xの[J] + [K]になるように置き換えることができ、私たちは聞かせて - 私たちは、上記の例の不等式が、[i]は、Xのあることを観察しました[k]はW =(j、i)に対して、DIS [I] = xで[I]、iは= vは、Jは= uは、元になる:DIS [U] + W(U、V)> = DIS [V]、コードは最短モデルの部分に関連付けることができるよう

IF(DIS [U](U、V)<= DIS [V、W +)
{ 
    DIS [V](U、V)W + DIS [U]を=。
}

これが正しいとリラクゼーションの動作は、それに類似していないのですか?

しかし、それは不平等の反対方向に見えますが、実際には、これは矛盾しません

上記のコードを達成するためにはDISである[U] + W(U、V)> DIS [V]、及び不等式のために、我々は、操作側を内蔵:不等式xのそれぞれについて、[I] - X [J] < = [K]、iはノードjとjの確立 - > iは、エッジを向け、[K]の右端には、Xを見つける[N-1] - X [0]の最大値を求めるようにされますN-1の両方ちょうどフィット、最短です。だから、問題を解決するためには、差動制約最短経路問題に変換されます。

解の存在

負環または単にないエンドポイントまでの存在にも存在する差動制約問題を解決する最短経路を解決するに表示されます

 

(1)負リング

星、X [0] <= T Tが無限小である - ネガティブ経路ループが発生した場合、それは、最短経路、すなわち最短経路が不平等の、パフォーマンス、すなわちX [N-1]が存在しない、無限に小さくすることができる表し結論は、X [N-1]であり、 - Xの最大値[0]は存在しません。チームの数に反映点がSPFA実装プロセス内のノードの数よりも大きいです。(一見代わりに実行時間を短縮する(num_node)をSQRTことができます)

(2)まで終わりません

この状況は、Xは、[N-1]とXとの間の制約なし[0]、Xが[N-ことを示す 1] - X [0]は、無限大の最大値、すなわち、X [N-1]、X [0]値の無限の数があります。DIS [N-1] = INFコード実装プロセスとして具現化。

記事への参照リンク:https://blog.csdn.net/my_sunshine26/article/details/72849441


注意を払います

そのために存在する可能性のある問題の1 負右のリング(このようなものに直面したときによく知られてdijstraは絶対に方法はありません)ので、我々はSPFAを使用する必要があります

アールにスタートした後、メリーランド州の不平等のタイトル2:XJ-XI> = A、我々はXI-XJを推測することができます<= - (処理した後、構成図に使用される)負の右側に注意を払います

3.条件指定されたタイトルは、必ずしも適切ではないので、我々はSPFA判定マップは、ユニコム(有用性の配列円)ではありません二回実行する必要があります。

コード:

#include <ビット/ STDC ++ H> 
名前空間STDを使用して、
0x3f3f3f3fの#define INF 
= 1005 CONST INT N。
const int型M = 40005; 
整数nは、ミリリットル、MD。
構造体EDGEは、{ 
    Wに、次のint型。
}エッジ[M]。
INTヘッド[N]、TOT。
ボイド追加{(int型のx、int型のyは、V INT)
    [X]エッジ[++ TOT] .next =ヘッド。
    エッジ【TOT] .TO = Y。
    エッジ【TOT] .W = V。
    ヘッド[X] = TOT。
} 
キュー<整数> Q。
INT VIS [N]、DIS [N]、サークル[N]; //円为指向TT的个数
空隙spfa(INT秒){ 
    memsetの(DIS、0x3fを、はsizeof(DIS))。
    memsetの(VIS、0、はsizeof(VIS))。
    memsetの(円、0、はsizeof(円))。
    q.push(S); 
    VIS [S] = 1、DIS [S] = 0; 
    しばらく(!q.empty()){
        q.front = INT()は、
		q.pop(); 
		VIS [今] = 0; 
        {ため(; I I =エッジ[I] .next I =ヘッド[今] INT)
            INTエッジTT = [I ] .TO; 
            IF(DIS [今]エッジ+ [I] .W <DIS [TT]){ 
                DIS [TT]がDIS [今]エッジ+ [I] .Wを=; 
                サークル[TT] =サークル[今] +1; //普通SPFA上、しかし条件は必ずしも右の対象ではない
                場合(円[TT]> = N){// n個のTTより有向エッジは自然条件ではない満たされている
                    プット( "-1");終了(0); 
                } 
                IF {(VIS [TT]!)
                    VIS [TT] = 1; 
                    q.push(TT); 
                } 
            } 
        } 
    } 

} 
int型のmain(){
    scanf関数( "%D%D%D"、&N、&ミリリットル、&​​MD)。
    {ため(; iは= mlの<I ++はI = 1 INT)
    	、B、D int型、
        scanf関数( "%D%D%D"、&、&B、&D)。
        (D、B)を加える; // AB <= D 
    } 
    のためには、(i = 1 int型; I <= MD; iが++){ 
    	A、B、Dをint。
        scanf関数( "%D%D%D"、&、&B、&D)。
        (-d、a、b)は追加; // BA> = D ==> AB <= - D因此为负权边
    } 
    spfa(0)。
    spfa(1)。
    IF(DIS [N] == INF)プット( " - 2")。
    他のprintf( "%dの"、DIS [N])。
    0を返します。
}

参照コード:https://www.luogu.org/blog/roy1994/solution-p4878

おすすめ

転載: www.cnblogs.com/myhnb/p/11761542.html