コンピュータネットワークの【CF555E】ケース

フェイス質問

https://www.luogu.org/problem/CF555E

問題の解決策

#include <cstdioを> 
する#include <iostreamの> 
する#include <ベクトル> 
の#include <アルゴリズム> 
の#include <CStringの> 使用して名前空間STD。構造体スタック{
   INT [ 200050 ]、尾;
  ブール B [ 200050 ]。
  ボイドクリア(){memsetの(0はsizeof(a)参照)。memset(B、0はsizeof(b)参照)。尾= 0 ;}
   ボイドプッシュ(INT X){++尾; [尾] = xと; B [X] = ;}
   int型の上部(){

 

戻り[テール];}
   ボイドポップ(){B [尾部]] = tail-- ;}
   BOOL ISIN(INT X){ 戻りB [X];} 
} STK。

INTの N、M、Q、DFN [ 200050 ]、低[ 200050 ]、cloct = 0 INTベル[ 200050 ]、CNT = 0 INT S [ 200050 ]、T [ 200050 ]。
ベクター < INT >に[ 200050 ]、ID [ 200050 ]。
ベクトル < 整数 >について[ 200050];
INT [F 200050 ] [ 25 ]、D [ 200050 ]。
int型 F1 [ 200050 ]、F2 [ 200050 ]。
BOOL ANS; 

ボイド tarjan(INT今、int型faid){ 
  低い[今] =のDFN [今] = ++ cloct。
  stk.push(今)。
  int型 I、L = [今] .size()に、
  (i = 0 ; iはL <; iは++)場合(!ID [今] [I] = faid){
       場合(!DFN [乃至[今] [I]]){ 
        tarjan(の[今] [I] 、ID [今] [I])。
        低[今] =([今] [I]に]、[今低低い)分。
    } 
    {
       場合(stk.isin(の[今] [I])){ 
          低い[今] = 分(低[今]、DFN [に対して[今] [I])。
      } 
    } 
  } 
  もし(低[今] == DFN [今]){
     int型のX;
    ++ CNT;
    実行{ 
      X = stk.top()。
      ベル[X] = CNT。
      stk.pop(); 
    } 一方(X =!今)。
  } 
} 

無効 maketree(int型今、int型 FA、int型を深い){
   int型 I、L = 約[今] .size()。
  F [今] [ 0 ] = FA。
  (i = 1 ; iは<= 19 ; iは++)F [今] [I] = F [F [今] [I- 1 ]] [I- 1 ]。
  D [今] = 深いです。
  (i = 0 ; iはL <; iは++)場合(!についての今] [I] = FA)maketree(約[今] [i]は、今、深い+ 1 )。
} 

ボイドワーク(INT U、INT V){ 
  F1 [U] + = 1 ; F1 [V] - = 1 ; 
  F2 [U] + = 1; F2 [V] + = 1 ;
  もし(D [U] < D [V])スワップ(U、V)。
  int型Iを、LCA;
  以下のために(私= 19 ; I> = 0 ; i--)場合(D [F [U] [I]]> = D [V])U = F [U] [I]。
  もし(U == V)LCA = U。
  {
     ための(I = 19 ; I> = 0 ; i--)であれば(F [U] [I] = F [v] [I]!)U = [U] [i]は、V = F のF [ V] [i]は、
    LCA = F [U] [ 0 ]。
  } 
  F2 [LCA] - = 2 
} 

無効 treesum(int型になりました、INT FA){
   int型 I、L = 約[今] .size()。
  (i = 0 ; iはL <; iは++)場合(約[今] [I] =!FA){ 
    treesum([今]について[I]、今)。
    F1 [今] + = F1 [i]は[]になりました[に関する]; 
    F2 [今] + = F2 [i]は[]になりました[に関する]; 
  } 
  もし(ABS(F1 [今])= ABS(F2 [今])!)ANS = ; 
} 

int型のmain(){
   int型 I、U、V、から、TO0。
  scanf関数(" %D%D%D "、&​​N、&M&Q)。
  (i = 1 ; I <= M、I ++){
      scanf関数(" %d個の%d個"、&​​U&V); 
      S [i]は = U。T [I] = V。
      [U] .push_back(V)へ。ID [U] .push_back(I)。
      [V] .push_backに(U)。ID [V] .push_back(I)。
  } 
  stk.clear()。
  (i = 1 ; iが<= N; iは++)場合 tarjan(I、 - ([I] DFN!)1 )。
  (i = 1 ; iが<= M; iは++ ){
       場合(!ベル[S [I] = ベル[T [I]]){ 
      約[ベル[S [i]は]一back(ベル[T [私]]); 
      約[ベル[T [I]]]一back(ベル[S [I])。
    } 
  } 
  のための(I = 1;私は= CNTを<; iは++)場合(F [i]が[!0 ])maketree(I、I、1 )。
  ANS = ;
  (i = 1 ; iが<= Q; iは++ ){ 
    scanf関数(" %d個の%のD "、&から、&TO0)。
    // のprintf( "%D%D \ n"は、ベルベル[TO0]、[から])。
    // のprintf( "%D%D \ n"は、F [ベル[]から] [19]、F [ベル[] TO0] [19])。
    もし(F [ベル[ から ] [ 19 ] = F [ベル[TO0] [!19 ]){ANS = 引き続き;}
     場合([BEL から!] =ベル[TO0])(ベル[動作から】ベル[TO0、])。
    // ヴァル[から] = 1; ヴァル= [に対して] - 1。
  }
   // (i = 1; iが<= N; iが++)のためCOUT <<ベル[I] <<」「。
  treesum(1 - 1 )。
  もし(ANS)プット(" はい")。他のプット(ノー)。
}

 

おすすめ

転載: www.cnblogs.com/shxnb666/p/11427337.html