22
33// 点分治,也叫重心分治,java版
44// 测试链接 : https://www.luogu.com.cn/problem/P3806
5- // 提交以下的code,提交时请把类名改成"Main"
6- // java实现的逻辑一定是正确的,但是本题卡常,无法通过所有测试用例
7- // 想通过用C++实现,本节课Code01_CentroidDecomposition2文件就是C++的实现
8- // 两个版本的逻辑完全一样,C++版本可以通过所有测试
5+ // 提交以下的code,提交时请把类名改成"Main",可以通过所有测试用例
96
107import java .io .IOException ;
118import java .io .InputStream ;
1512public class Code01_CentroidDecomposition1 {
1613
1714 public static int MAXN = 10001 ;
18- public static int MAXV = 15000001 ;
19- public static int n , m , total ;
15+ public static int MAXV = 10000001 ;
16+ public static int n , m , maxq , total ;
2017 public static int [] query = new int [MAXN ];
2118
2219 public static int [] head = new int [MAXN ];
@@ -46,14 +43,13 @@ public static void addEdge(int u, int v, int w) {
4643 head [u ] = cntg ;
4744 }
4845
49- // 找重心递归版,java会爆栈,C++可以通过
50- public static void getCentroid1 (int u , int fa ) {
46+ public static void getCentroid (int u , int fa ) {
5147 siz [u ] = 1 ;
5248 maxPart [u ] = 0 ;
5349 for (int e = head [u ]; e > 0 ; e = nxt [e ]) {
5450 int v = to [e ];
5551 if (v != fa && !vis [v ]) {
56- getCentroid1 (v , u );
52+ getCentroid (v , u );
5753 siz [u ] += siz [v ];
5854 maxPart [u ] = Math .max (siz [v ], maxPart [u ]);
5955 }
@@ -64,61 +60,11 @@ public static void getCentroid1(int u, int fa) {
6460 }
6561 }
6662
67- // 讲解118,递归改迭代需要的栈
68- public static int [][] ufe = new int [MAXN ][3 ];
69- public static int stacksize , u , f , e ;
70-
71- public static void push (int u , int f , int e ) {
72- ufe [stacksize ][0 ] = u ;
73- ufe [stacksize ][1 ] = f ;
74- ufe [stacksize ][2 ] = e ;
75- stacksize ++;
76- }
77-
78- public static void pop () {
79- --stacksize ;
80- u = ufe [stacksize ][0 ];
81- f = ufe [stacksize ][1 ];
82- e = ufe [stacksize ][2 ];
83- }
84-
85- // 找重心迭代版
86- public static void getCentroid2 (int cur , int fa ) {
87- stacksize = 0 ;
88- push (cur , fa , -1 );
89- while (stacksize > 0 ) {
90- pop ();
91- if (e == -1 ) {
92- siz [u ] = 1 ;
93- maxPart [u ] = 0 ;
94- e = head [u ];
95- } else {
96- e = nxt [e ];
97- }
98- if (e != 0 ) {
99- push (u , f , e );
100- int v = to [e ];
101- if (v != f && !vis [v ]) {
102- push (v , u , -1 );
103- }
104- } else {
105- for (int ei = head [u ]; ei > 0 ; ei = nxt [ei ]) {
106- int v = to [ei ];
107- if (v != f && !vis [v ]) {
108- siz [u ] += siz [v ];
109- maxPart [u ] = Math .max (siz [v ], maxPart [u ]);
110- }
111- }
112- maxPart [u ] = Math .max (maxPart [u ], total - siz [u ]);
113- if (centroid == 0 || maxPart [u ] < maxPart [centroid ]) {
114- centroid = u ;
115- }
116- }
117- }
118- }
119-
12063 public static void getDistance (int u , int fa , int w ) {
12164 dis [u ] = dis [fa ] + w ;
65+ if (dis [u ] > maxq ) {
66+ return ;
67+ }
12268 arr [++cnta ] = dis [u ];
12369 for (int e = head [u ]; e > 0 ; e = nxt [e ]) {
12470 int v = to [e ];
@@ -164,8 +110,7 @@ public static void compute(int u) {
164110 if (!vis [v ]) {
165111 total = siz [v ];
166112 centroid = 0 ;
167- // getCentroid1(v, u);
168- getCentroid2 (v , u );
113+ getCentroid (v , u );
169114 compute (centroid );
170115 }
171116 }
@@ -185,11 +130,11 @@ public static void main(String[] args) throws Exception {
185130 }
186131 for (int i = 1 ; i <= m ; i ++) {
187132 query [i ] = in .nextInt ();
133+ maxq = Math .max (maxq , query [i ]);
188134 }
189135 total = n ;
190136 centroid = 0 ;
191- // getCentroid1(1, 0);
192- getCentroid2 (1 , 0 );
137+ getCentroid (1 , 0 );
193138 compute (centroid );
194139 for (int i = 1 ; i <= m ; i ++) {
195140 if (ans [i ]) {
0 commit comments