サマースクールキャンプオフ以上の2019頭の牛(6位)H:運転士(最短+確率)

問題の意味:無向グラフが与えられると、アリスは、点Aのセットから選択され、ボブはCXKは、コーパス内のポイントを選択し、B点のセットから選択されます。次に、「コレクションのポイントの最短距離に3を」期待をお願いします。

考える:裸のタイトルは、3つのポジションを考えると、どこで設定された最小価格から行くように頼まれました。その質問は、あなたが答えを更新することができ、三点走行3回SPFAです。そして、この質問はCxkは、非常に厄介な、しかし、右側が1で、Tmは直接、まだそれを拡張BFSされていないことを指摘しています。次いでDIS [i]の列挙位置アリスとボブは、DISA [I = ] + DISB [j]を、 その後、拡張することができます。問題となる可能性がログでこれをオーバーしないように注意してください。

<ビット/ STDC ++ H>の#include
 の#defineは長い長いっ
 の#define REPは(iは、、B)のための式(I ++; iが= Bを<Iは= INT)
 使用して 名前空間STDを、
const  int型 MAXN = 200010 ;
const  int型 INF = 1E9;
INT DISA [ 21 ] [MAXN]、DISB [ 21 ] [MAXN]、[MAXN]、B [MAXN]。
INT Laxt [MAXN]、次に[MAXN]に[MAXN]、CNT、N。LLの合計。
ボイド追加(INT U、INT V)
{ 
    次に[ ++ CNT] = Laxt [U]。Laxt [U] = CNT。[CNT] =にV。
} 
ボイド BFS(INT DIS []、INT ST)
{ 
    担当者(I、1、N)DIS [I] = INF。DIS [ST]は= 0 
    キュー < 整数 > Q; q.push(ST);
    しばらく(!q.empty()){
         int型のu = q.front(); q.pop();
        int型 ; I = I iは= Laxt [U] {次に[I])
             であれば(== [[I]へ] DIS {INF)
                [I]へ] DIS = DIS [U] + 1 
                q.push(TO [I])。
            } 
        } 
    } 
} 
int型NUM [MAXN]、[MAXN] C、[MAXN] DIS。
空隙)(解決// 基数排序+两个单调队列
{ 
    担当者(I、0、N + N)NUM [I] = 0 ; 
    担当者(I、0、N)NUM [DIS [I] ++、D [I] = 0 ; 
    担当者(I、1、N + N)NUM [I] + = NUM [I- 1 ]。
    担当者(I、1 C、N)[NUM [DIS [I]] - ] = I。
    キュー < 整数 > Q1、Q2; 
    担当者(I、1 、N)q1.push(C [I])。
    一方、(!q1.empty()||!q2.empty()){
         場合(q2.empty()||(!q1.empty()&&!q2.empty()&& DIS [q1.front()] < DIS [q2.front()])){
             int型、U =q1.front(); q1.pop();
            int型 ; I I = iは= Laxt [U] {次に[I])
                 であれば(> DIS [U] + [I]へ] DIS 1 {)
                    DIS [に[I] = DIS [U] + 1 
                    q2.push(TO [I])。
                } 
            } 
        } 
        {
             int型、U = q2.front()。q2.pop();
            int型 ; I I = iは= Laxt [U] {次に[I])
                 であれば(> DIS [U] + [I]へ] DIS 1 {)
                    DIS [に[I] = DIS [U] + 1; 
                    q2.push(TO [I])。
                } 
            } 
        } 
    } 
    担当者(I、1、N)の和+ = DIS [i]は、
} 
int型のmain()
{ 
    int型 C = 0 、T、M、A、B、U、V。
    scanf関数(" %のD "、&T)。
    一方、(T-- ){ 
        scanf関数(" %d個の%のD "、&​​N、&M)。
        担当者(I、1、N)Laxt [I] = 0 ; CNT = 0 ; 
        担当者(I、1 、M){ 
           scanf関数(" %d個の%d個"、&​​U&V); 
           (V、U)を追加します。(V、U)を追加。
        } 
        のscanf(" %dの"、&​​A)。担当者(I、1、A)のscanf(" %dの"、および[I])。
        scanf関数(" %のD "、&​​B)。担当者(I、1、B)のscanf(" %dの"、&B [I])。
        担当者(I、1 、A)BFS(DISA [I]、[I])。
        担当者(I、1 、B)BFS(DISB [I]、B [I])。
        合計 = 0 ; 
        担当者(I、1 、B){ 
             担当者(K、1、N)DIS [k]はDISA [I] [K] + = DISB [j] [k]を、
             解決する(); 
        } 
        LL ANS = 1LL * A * B * N。
        LL G = __gcd(ANS、合計)。
        printf(" ケース#%dの:"、++ C);
        もし(G ==和)のprintf(" %LLDする\ n "、和/ G)
        のprintf(" %LLD /%LLD \ n "、和/ gで、ANS / G)
    } 
    戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/hua-dong/p/11306550.html