私は昨年のこの質問に木の練習を書きましたが、事前に記憶された地図XP短鎖のようですが、いくつかのポイントを持っていた覚えています
木の部分は貪欲+のDFSすることができます。
ツリーのベースリング、nはエッジがする^ 2暴力的なブレーク列挙の一部... 88 '
プラスの高速読み出しが、ベクトルを削除...要するに、私はファックが96 'に最適化されました
以上の酸素...
正の解は、nlognと言われて、tarjanリングによって宣告されているようです
(そしてその次の拡張バージョンを行います...
コードは以下の通りです
#include <cstdioを> する#include <iostreamの> する#include <cmath> の#include <CStringの> に#define MogeKo qwq の#include <アルゴリズム> の#include <ベクトル> 使用して 名前空間STD。 const int型 MAXN = 5005 ; INTのN、M、X、Y、K。 INT [MAXN]、[MAXN] B、TX [MAXN]、TY [MAXN] BOOL VIS [MAXN]。 ベクター < INT > [MAXN] V。 INTはREAD(){ int型のx = 0、F = 1 。 CHAR CH =getchar関数(); 一方、(CH < ' 0 ' || CH> ' 9 ' ){ 場合(CH == ' - ')、F = - 1 。 CH = GETCHAR()。 } 一方(' 0 ' <= CH && CH <= ' 9 ' ){ X = X * 10 + CH- ' 0 ' 。 CH = GETCHAR()。 } 戻りのx *のF。 DFS(INT U、INT FA、int型のx、int型のY){ B [ ++ K] = U。 もし(VIS [U])のリターン; VIS [U] = 真; 以下のために(int型 i = 0 ; iはV <[U] .size(); iは++ ){ 場合(V [U] [I] == FA)続けます。 もし(U == X && V [U] [I] == y)を続けます。 場合(UはY == && V [U] [I] == x)を続けます。 DFS(V [U] [i]は、U、X、Y)。 } を返します。 } ボイド更新(){ ため(int型 iは= 1 ; iがn = <; iは++ ){ 場合(B [i]は< [I]){ ための(int型 J = I; J <= nであり、j ++ ) [J ] =のB [J]。 破ります; } もし、(B [I]> [i])とブレーク。 } を返します。 } int型のmain(){ N =(読み取り)、M = read()は、 以下のために(int型 = Iを1 ; I <= M; I ++ ){ X=()、Y =読み出す(リード)。 V [X] .push_back(Y)。 V [Y] .push_back(X)。 TX [I] = xで、TY [I] = yと、 } のために(int型 I = 1を iが++; iが<= N ) 、ソート(V [i]が.begin()、V [i]は.END())。 [ 1 ] = N。 もし(m個の== N- 1 ) DFS(1、0、0、0 )、更新()。 そう するために(int型 I = 1 ; I <= M; I ++){ K = 0; memsetの(VIS、0、はsizeof (VIS))。 DFS(1、0 、TX [i]は、TY [I])。 もし(K <N)が継続し、 更新(); } のための(int型 i = 1 ; iが<= N; iが++ ) のprintf(" %dの" 、[I])。 リターン 0 ; }