コード:
#include <cstdioを> する#include <アルゴリズム> の#include <CStringの> する#include <地図> の#include <ベクトル> の#include <スタック> の#include <キュー> の#define setIO(S)freopenは(S ".IN"、」 R "STDIN)、freopenは(S" .out」を、 "W"、STDOUT) の#define MAXN 1002002 使用して名前空間std。 するchar * P1、P2 *、BUF [100000]。 #define NC()(P1、P2 == &&(P2 =(P1 = BUF)+関数fread(BUF、1,100000、STDIN)、P1 == P2)EOF:* P1 ++) int型RD(){int型のx = 0 ; チャーC = NC()。一方、(C <48)C = NC()。一方、(C> 47)x =(((X << 2)+ X)<< 1)+(C ^ 48)、C = NC()。Xを返す;} ベクトル<整数> G [MAXN]。 スタック<整数> S; N INT、M、エッジ。 int型のTM [MAXN]、HD [MAXN << 1]、 int型のSIZ [MAXN]、トップ[MAXN]、[MAXN] FA、 INT IDX [MAXN << 1]、ID [MAXN << 1]。 インラインボイドaddedge(INT U、INT V、INT C){ NEX [++エッジ] = HD [U]、HD [U] =エッジは、[エッジ]にVを= ID [エッジ]はCを=。 } ボイドDFS1(INT U、INT FF){ DEP [U] = DEP [FF] + 1、SIZ [U] = 1、FA [U] = FFを、 以下のために(INT I = HD [U]; I; I = NEX [I]){ int型V =乃至[I]。 (vは== FF)続けるならば、 IDX [V] = ID [i]は、DFS1(V、U)、SIZ [U] + = SIZ [V]。 IF(SIZ [V]> SIZ [息子[U])息子[U] = V。 } } ボイドDFS2(INT U、INT TP){ トップ[U]はTPを=。 IF(息子[U])DFS2(息子[U]、TP)。 以下のために(INT I = HD [U]; I; I = NEX [I]){ int型V =乃至[I]。 もし(V == FA [U] || V ==息子[U])続けます。 DFS2(V、V); } } インラインINT LCA(int型のx、int型のY){ 一方、(DEP [U]> DEP [LCA]){ 一方(上部[X] ^トップ[Y]){ DEP [トップ[X]]> DEP [トップ[Y] X = FA [TOP [X]:Y = FA [トップ[Y]。 } 戻りDEP [X] <DEP [Y]は、x:yの。 } 構造体オプト{ int型OPT、X、Y。 } OP [MAXN]。 構造体ユニオン{ INT P [MAXN]。 インラインボイドのinit(){ ため(INT i = 0; I <MAXN; ++ I)のP [I] = I。 } INT(INT X){見つける ?戻りP [X] == X X:Pは[X] =(P [X])を見つけます。 } }ブラック、ホワイト。 インラインボイドマーク(INT U、INT LCA、INT CUR){ U = TM [U] black.find(U):U。 black.p [U] = FA [U]。 U = FA [U]。 TM [U] = CUR。 (!TM [FA [U]]){もし } 他{ int型、Y = black.find(FA [U])。 black.p [U] = Y。 UはYを=。 } } } インラインボイド更新(INT U、V INT、INTのCUR){ int型LCA = LCA(U、V)。 マーク(U、LCA、CUR)、マーク(V、LCA、CUR)。 } インラインボイド変化(INT U){ white.p [U] = white.find(FA [U])。 } int型のmain(){ // setIO( "入力")。 scanf関数( "%d個の%のD"、&N、&M)。 {(; iがN <++ iが1 = INT)のための V、U int型。 U = RD()、V = RD()。 addedge(U、V、I)、addedge(V、U、I)。 } DFS1(1,0)、DFS2(1,1)、black.init()。 (I 1 = int型; I <= M; ++ i)について{ OP [I] .OPT = RD()。 IF(OP [I] .OPT == 1)OP [I] .X = RD()。 IF(OP [I] .OPT == 2)OP [I] .X = RD()、OP [I] .Y = RD()、更新(OP [I] .X、OP [I] .Y、私); } white.init()。 (I = 2をint型++ I; iが<= n)のためのG [TM [I] == 0 M + 1:TM [I]]。一back(I)。 M + =(G [M + 1] .size()> 1)。 { - (I; I> = 1、I = mは整数)のための {(G [i]が.size())場合 、INT J = 0(のために、J <G [I] .size(); ++ J )変化(G [I] [J])。 }そうであれば(OP [I] .OPT == 1){ S.push(white.find(OP [I] .X))。 } } ながら(!S.empty()){ のprintf( "%d個の\ n"、IDX [S.top()])。S.pop(); } 0を返します。 }