WOJの#4709失われました

WOJの#4709失われました

タイトル説明

    人形が誤って宝の地図を持って、彼は宝の道路の検索に着手しました。後で同じ場所に行くために多くの、多くのステップでは、人形は彼が失われた決定しました。非常に怒っている人形は、彼は彼自身さえ失ったが、また、最小のリング上で失われたので、賢明なパラディンを感じました。そこで彼は、どのくらいの最小リングの各点から知りたいと思いました。宝の地図は、点n及びmのエッジに抽象化することができ、正のエッジの重みは、今では各点胴回りである介して取得する必要がある、すべての無向グラフです。

入力形式

    2つの数の最初の行は、n、mは、点とエッジを表します。次の3行m行U、Vの各整数、lは点UおよびV長さL無向エッジの間に発現しました。

出力フォーマット

    出力の数nは、各ポイントは、経過ガースを表す-1出力がない場合。

データ範囲

    N 300 m個の40000を

問題の解決策

  私は、最短でのポイントから始まる私が根付い最短パスツリーを構成しています。知るやすい、私最小点を通るリングプラスパスは、最短経路ツリーであるべきであるが、非エッジ構成です。したがって、我々は、そのようなアルゴリズムを考え出すことができる:各点iについて、我々は、その最短経路ツリールートと、非列挙木に構築、LCAの両端点をエッジは、2つのIで、Iである場合最短加えた合計コラージュ答えを更新しようとする権利のポイント。この部分の時間の複雑さはO(nmlogn)でなければなりません。NとMはわずか300のみ40,000、それは完全に可能なアルゴリズムであることに留意しました。

  詳細のいくつかに注意してください。

  1、長い長い開くことを忘れないでください。

  2、日本語文は、以前は両側のみ最小重量を残し、ループバック。

  算出され、範囲データにおいて、フロイドダイクストラN倍高速走行より:最短経路アルゴリズムの選択に3、。

  コードを入れてください:

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
#define N 310
 の#define M 100010
 の#define LL長い長
 の#define 0x3f3f3f3f INF
 の#define PII対<整数、整数>
 の#define MP make_pair
 の#define PB一back
 INT NUM = 1 、[N] F。
構造体ノード{
     int型、U、V、W NXT。
} E [M << 1 ]。
ボイド追加(INT U、INT V、INT W){eは[++ NUM] =(ノード){U、V、W、[U] F}; [U] = F NUM;}
 // グラフを構築します
LL ANS [N]、融点[N] [N]、DIS [N] [N]。
ボイドフロイド(int型N){
     ためのint型のk = 1 ; kは<= N; ++ k個のためにint型 i = 1 ; iがn = <I ++ のためのINT J = 1 ; J <= N; J ++)DISを[I] [J] =分(DIS [I]、[J]、DIS [I] [K] + DIS [K] [J])。
} 
// 最短パス
INT INQ [M << 1 ]、[N]を追加します。
ベクター < INT > G [N]。
のビルド(int型、Uをint型{ST)の
     ためにint型 ; I I = iが[U] F = {E [I] .nxt)
         int型、V = E [I] .V、W = E [I] .W。
        もし(DIS [ST] [V] == DIS [ST] [U] W + &&!追加[V]){ 
            [I] INQ [I ^ =のINQは1 ] = 1 ; [V] =追加1 、G [ U] .pb(V); G [V] .pb(U);ビルド(V、ST)。
        } 
    } 
} 
// ツリーの構築
int型のDEP [N]、FAZ [N]、SZE [N]、息子[N]、上位[N]を、
ボイド DFS1(INT U、INT FA、int型のD){ 
    DEP [U] = D; SZE [U] = 1 ; FAZ [U] = FA。
    以下のためのint型I = 0 ; I ^ G [U] .size(); iが++ ){
         INT = V G [U] [I]。
        もし(== FA V)続けます
        DFS1(V、U、D + 1); SZE [U] + = SZE [V]。
        もし(!息子[U] || SZE [V]> SZE [息子[U]])息子[U] = V; 
    } 
} 
ボイド DFS2(int型 Uを、int型ST)を{ 
    TOP [U] = ST。
    もし(!息子[U])のリターン; 
    DFS2(息子[U]、ST); 
    以下のためにint型 i = 0 ; I ^ gで[U]は.size(); iは++ ){
         int型V = G [U] [I]。
        もし(V == FAZ [U] || V ==息子[U])続けます
        DFS2(V、V); 
    } 
} 
int型 LCA(int型のx、int型のY){
     int型 XX = TOP [X]、YY = TOP [Y]。
    一方、(XX =!YY){
         場合(DEP [XX] < DEP [YY]){スワップ(XX、YY)、スワップ(X、Y);} 
        X = FAZ [XX]、XX = TOP [X]。
    } 
    もし(DEP [X]> DEP [Y])リターンY。
    リターンのx; 
} 
// ツリー解剖 
インラインint型リード(){ 
     int型X = 0、F = 1char型のCH;
    以下のための(CH = getchar関数();(CH < ' 0 ' || CH> ' 9 ')&& CH =!' - ' ; CH = getchar関数());
    もし(CH == ' - '){F = - 1 ; CH = GETCHAR();}
     一方(CH> = ' 0 ' && CH <= ' 9 '){X =(x << 3)+(X < < 1)+ CH- ' 0 'X * F; 
} 
// 读优
整数N、M。
ボイドライト(int型I){
     場合(ANS [I] ^ ANS [ 0 ])のprintf(" %のLLD " 、ANS [I])。
    のprintf(" -1 " ); 
} 
int型のmain(){
     int型 X、Y、Z、和= 0 
    N =読み取る(); M = 読み取ります()。
    memset(MP、0x3fをはsizeof (MP))。
    memset(ANS、0x3fをはsizeof (ANS))。
    memsetの(DIS、0x3fをはsizeof (DIS))。
    以下のためにint型私= 1 ; I <= M; iは++ ){ 
        X =読み取る(); Yが読み出さ=(); Z =を読み取ります()。
        あれば(私は= Nを<)DIS [i]は[I] = 0 ;
        もし(x == y)は{ANS [X] =分(ANS [x]は、(LL)Z); 引き続き;}
         もし(MP [X] [Y] <= Z)続けます ++;、(X、Y、Z)を追加(X、Y、Z)を追加し、LL TMP = DIS [X] [Y]。
        DIS [X] [Y] = DIS [Y] [X] = 分(TMP、(LL)Z); 
        MP [X] [Y] =融点[Y] [X] = MAX(TMP、(LL)Z); 
    } 
    フロイド(N)
    ためにint型 i = 1 ; iが<= N; iが++ ){ 
        memsetの(追加、0はsizeof (入れます))。
        memset(DEP、0はsizeof (DEP))。
        memset(FAZ、0はsizeof (FAZ))。
        memset(SZE、0はsizeof (SZE))。
        memsetの(息子、0はsizeof (息子)); 
        memsetの(トップ、0はsizeof (トップ)); 
        memset(INQ、0はsizeof (INQ))。
        以下のためのint型J = 1 ; J <= N; J ++ )G [J] .clear(); 
        構築(I、I); DFS1(I、I、1 ); DFS2(I、I);
        int型、J = 2、J <= NUM; J + = 2 ){
             int型、U = E [J] .U、V = E [J] .V、W = E [J] .W; LL TMP = DIS [ I] [U] + DIS [I] [V] + W。
            もし(INQ [J] || ANS [I] <= TMP || LCA(U、V)^ i)が継続し
            ANS [I] = TMPと、
        } 
        (i)を書き込みます。
    } 
    戻り 0 
}

 

  

おすすめ

転載: www.cnblogs.com/doyo2019/p/11564209.html