BZOJ1003&羅区P1772--物流及び輸送[] DP +最短ZJOI2006

トピックリンク:https://www.luogu.com.cn/problem/P1772

羅バレー:

制限時間1.00s
メモリ制限125.00メガバイト
 
BZOJ:
制限時間:10秒   メモリ制限:162メガバイト

説明

  物流会社は、桟橋A Bに桟橋から商品の数を入れて 完全な動作に大きな、n個必要日数よりも商品として。商品の輸送は、一般的に有効にする必要があり
、いくつかのドックを停止します。物流会社は、多くの場合、全体の輸送プロセスの厳格な管理と追跡の実施のための一定の輸送ルートを設計します。様々なによる
要因が存在し、時々ピアロードおよびアンロード貨物ではないであろう。今回はその品物が時間通りに目的地に到達できることを、輸送ルートを変更する必要があります。しかし、
変更されたルートは、非常に面倒なことで、追加コストをもたらすでしょう。そのため、物流会社は、n個日間の輸送計画を設定したいと考えているので、トータルコスト
できるだけ低いように。

入力

  最初の行は、4つの整数n個(1 <= N <=である 100)、M(1 <= M <= 20)、K 、およびe。N Mは、ドックの総数を表し、貨物の輸送のために必要な日数を表し、Kは表し
輸送ルートのために必要な各変形コスト。各列E列次の経路が接続され、これらの二つの端子の符号化のために、それぞれ、三つの整数を含む、記載されている
数と、これらの長さ(> 0)。港は、端末Bをm番号ここで、Aは、1の番号が付け。単位長さ当たりの輸送コストは1です。両方向のルート。
の行は、整数dであり、各ラインの後のD線は、3つのP(1 <P <M)の整数であり 、B(1 <= <= B <= N)。Pは、コードの数を表し
ロードおよびアンロード貨物B(両端を含む)することができない日々ヘッダ。マリーナでは、おそらく複数の期間には使用できません。しかしながら、任意の時間がそこの少なくとも一つである
、桟橋から桟橋Bに物品搬送経路A.

出力

  これは、最小の総コストを表す整数を含みます。総一日路長のコスト= N + K *及び輸送ルート変更の輸率。

サンプル入力

5 10 8
1 2 1
1 3 3
1 4 2
2 3 2
2 3 3
3 4 1
3 5 2
4 5 2
4
2 2 3
3 1 1
3 3 3
4 4 5

サンプル出力

32
3日間で1-4-5 //前に、1-3-5、二日後に行くように(2 + 2)* 3 +(3 + 2)* 2 + 10 = 32の総コスト

私たちは、最初の質問を理解する必要があります。一日あたりの被験者は1からmまでのボートを意味します、N M n回に1日を実行する必要があります。
データは、この問題は解決が実際には非常に暴力的であるので、最小コストを伴う、我々はDPを考えることができるはず、比較的小さいので、その後、DPの最小コストは、[i]は私の日の代表前、その後、DP式はここにリストする必要があります。
DP [I] =分{DP [I]、DP [J-1] +(I-J + 1)* DIS [M] + K}。
 おそらく、最初からj番目の日は、その後、現在の最低価格は最小コストプラスiがm + kまでの最短距離を乗じた時間帯にj番目の前日J-1日であることを意味し、これらの変更。
そして、次の日にJの日は、私が通過できることを確実にするためにとても重要です。実際には、非常に暴力的な、我々は2次元配列の暴力などでダイレクトマーキング:
以下のためにINT iが= 1 ; I <= D; I ++ ){
     int型のP、L、R。
    (P)(L)の(R)
    int型 ; J <= R J = L J ++)ポット[P] [J] = 
}

マーキングした後、ほとんどの短絡のセットを実行しているバックパックが付いています:

以下のためにINT iが= 0 ; I <= N; I ++)DP [I] = INF。
DP [ 0 ] = - K。
以下のためにINT iが= 1 ; I <= N; I ++ ){
    memsetの(distry、はsizeof distry)。
    int型 J = I; J> = 1 ; j-- ){
         ためのint型 K = 1 K ++; K <= M であれば(ポット[K] [J])distry [K] = 
        Dij(N、M);
        もし(DIS [M] == INF)ブレーク
        DP [I] =分(DP [I]、DP [J- 1 ] +(I-J + 1)* DIS [M] + K)。
    }
}

ルートI jが実現可能であることを確実にするために、我々は死ぬことはない前に一度、この代わって、後ろからきたプッシュすることができ、あなたが直接破ることができるし、次に実行dijのが最短ですが、私は時に裁判官のアドオンを覚えて特別宣告存在distry配列。スクロールアレイはその後、波に逃げています。

以下は、ACコードです:
書式#include <cstdioを> 
する#include <キュー> 
の#include <CStringの> 
の#include <アルゴリズム> 
書式#include <iostreamの>
 使用して 名前空間をSTD。

#define LL長い長いです

const  int型 MAC = 200 ;
const  int型 INF = 1E9 + 10 

構造体のノード
{
    int型に、次の、ワット。
}例えば、[MAC << 1 ]。
構造体qnode
{
    int型のID。
    LL D;
    ブール 演算子 <(CONST qnode&)のconst {
         リターン D> 広告。
    }
}。
[MAC]、DIS [MAC]をDPちゃいます。
BOOL VIS [MAC]、ポット[MAC] [MAC]、distry [マック]。
INTヘッド[MAC]、NUM = 0 

無効アドオン(int型のu、int型 V、int型ワット)
{
    例えば、[ ++ NUM] = ノード{V、ヘッド[U]、W}。
    ヘッド[U] = NUM。
}

イチジク(もし nは、あなたはM)
{
    memsetの(VIS、はsizeof VIS)。
    以下のためにINT iが= 1 ; I <= M; I ++)DIS [I] = INF。
    DIS [ 1 ] = 0 ;
    PRIORITY_QUEUE <qnode> Q;
    q.push(qnode { 10 })。
    しばらく(!q.empty()){
        今qnode = q.top()。
        q.pop();
        INTの ID = now.id、D = now.d。
        もし(VIS [ID])続けます
        VIS [ID] = 以下のためにINT iがヘッド[ID]を=; iが=! - 1 ; I = 例えば、[I] .next){
             int型 V = 例えば、[I] .TO。
            もし(!distry [V] && DIS [ID] +たとえば[i]の.W < DIS [V]){
                DIS [V] = DIS [ID] + たとえば[i]の.W。
                q.push(qnode {V、DIS [V]})。
            }
        }
    }
}

 INTX)
{
    int型 F = 0 ;
    チャー CH = GETCHAR()。
    一方、(CH> ' 9 ' || CH < ' 0 ')CH = GETCHAR()。
    一方、(CH> = ' 0 ' && CH <= ' 9 ')、F =(F << 1)+(F << 3)+ CH- ' 0 '、CH = GETCHAR()。
    X = F。
}

int型のmain()
{
    // freopenは( "in.txt"、 "R"、STDIN)。
    整数N、M、K、E。
    memsetの(頭、 - 1はsizeof ヘッド)
    (N)(M)。(K); (E);
    INT iは= 1 ; I <= E I ++ ){
         int型、U、V、W。
        (U)(V); (W)
        追加(U、V、W);アドオン(V、U、W)。
    }
    int型D;
    (D)
    memsetの(鍋、はsizeof ポット)。
    memsetの(distry、はsizeof distry)。
    以下のためにINT iが= 1 ; I <= D; I ++ ){
         int型のP、L、R。
        (P)(L)の(R)
        int型 ; J <= R J = L J ++)ポット[P] [J] = 
    }
    以下のためにINT iが= 0 ; I <= N; I ++)DP [I] = INF。
    DP [ 0 ] = - K。
    以下のためにINT iが= 1 ; I <= N; I ++ ){
        memsetの(distry、はsizeof distry)。
        int型 J = I; J> = 1 ; j-- ){
             ためのint型 K = 1 K ++; K <= M であれば(ポット[K] [J])distry [K] = 
            Dij(N、M);
            もし(DIS [M] == INF)ブレーク
            DP [I] =分(DP [I]、DP [J- 1 ] +(I-J + 1)* DIS [M] + K)。
        }
    }
    printf(" %のLLD \ n " 、DP [N])。
    リターン 0 ;
}

 

 
 

おすすめ

転載: www.cnblogs.com/lonely-wind-/p/12048443.html