Skip to content

Commit 7724154

Browse files
committed
modify code
1 parent b5f510f commit 7724154

File tree

2 files changed

+386
-0
lines changed

2 files changed

+386
-0
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
package class183;
2+
3+
// 点分治,也叫重心分治,java版
4+
// 测试链接 : https://www.luogu.com.cn/problem/P3806
5+
// 提交以下的code,提交时请把类名改成"Main"
6+
// java实现的逻辑一定是正确的,但是本题卡常,无法通过所有测试用例
7+
// 想通过用C++实现,本节课Code01_CentroidDecomposition2文件就是C++的实现
8+
// 两个版本的逻辑完全一样,C++版本可以通过所有测试
9+
10+
import java.io.IOException;
11+
import java.io.InputStream;
12+
import java.io.OutputStreamWriter;
13+
import java.io.PrintWriter;
14+
15+
public class Code01_CentroidDecomposition1 {
16+
17+
public static int MAXN = 10001;
18+
public static int MAXV = 20000001;
19+
public static int n, m, total;
20+
public static int[] query = new int[MAXN];
21+
22+
public static int[] head = new int[MAXN];
23+
public static int[] nxt = new int[MAXN << 1];
24+
public static int[] to = new int[MAXN << 1];
25+
public static int[] weight = new int[MAXN << 1];
26+
public static int cntg;
27+
28+
public static boolean[] vis = new boolean[MAXN];
29+
public static int[] siz = new int[MAXN];
30+
public static int[] maxp = new int[MAXN];
31+
public static int centroid;
32+
33+
public static int[] dis = new int[MAXN];
34+
public static int[] valArr = new int[MAXV];
35+
public static int cntv;
36+
public static int[] que = new int[MAXV];
37+
public static int cntq;
38+
public static boolean[] judge = new boolean[MAXV];
39+
40+
public static boolean[] ans = new boolean[MAXN];
41+
42+
public static void addEdge(int u, int v, int w) {
43+
nxt[++cntg] = head[u];
44+
to[cntg] = v;
45+
weight[cntg] = w;
46+
head[u] = cntg;
47+
}
48+
49+
// 找重心递归版,java会爆栈,C++可以通过
50+
public static void getCentroid1(int u, int fa) {
51+
siz[u] = 1;
52+
maxp[u] = 0;
53+
for (int e = head[u]; e > 0; e = nxt[e]) {
54+
int v = to[e];
55+
if (v != fa && !vis[v]) {
56+
getCentroid1(v, u);
57+
siz[u] += siz[v];
58+
maxp[u] = Math.max(siz[v], maxp[u]);
59+
}
60+
}
61+
maxp[u] = Math.max(maxp[u], total - siz[u]);
62+
if (maxp[u] < maxp[centroid]) {
63+
centroid = u;
64+
}
65+
}
66+
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+
maxp[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+
maxp[u] = Math.max(siz[v], maxp[u]);
110+
}
111+
}
112+
maxp[u] = Math.max(maxp[u], total - siz[u]);
113+
if (maxp[u] < maxp[centroid]) {
114+
centroid = u;
115+
}
116+
}
117+
}
118+
}
119+
120+
public static void getDistance(int u, int fa, int w) {
121+
dis[u] = dis[fa] + w;
122+
valArr[++cntv] = dis[u];
123+
for (int e = head[u]; e > 0; e = nxt[e]) {
124+
int v = to[e];
125+
if (v != fa && !vis[v]) {
126+
getDistance(v, u, weight[e]);
127+
}
128+
}
129+
}
130+
131+
public static void calc(int u) {
132+
dis[u] = 0;
133+
cntq = 0;
134+
for (int e = head[u]; e > 0; e = nxt[e]) {
135+
int v = to[e];
136+
int w = weight[e];
137+
if (!vis[v]) {
138+
cntv = 0;
139+
getDistance(v, u, w);
140+
for (int k = cntv; k > 0; k--) {
141+
for (int l = 1; l <= m; l++) {
142+
if (query[l] >= valArr[k]) {
143+
ans[l] |= judge[query[l] - valArr[k]];
144+
}
145+
}
146+
}
147+
for (int k = cntv; k > 0; k--) {
148+
que[++cntq] = valArr[k];
149+
judge[valArr[k]] = true;
150+
}
151+
}
152+
}
153+
for (int i = cntq; i > 0; i--) {
154+
judge[que[i]] = false;
155+
}
156+
}
157+
158+
public static void solve(int u) {
159+
vis[u] = true;
160+
judge[0] = true;
161+
calc(u);
162+
for (int e = head[u]; e > 0; e = nxt[e]) {
163+
int v = to[e];
164+
if (!vis[v]) {
165+
total = siz[v];
166+
centroid = 0;
167+
maxp[centroid] = n;
168+
// getCentroid1(v, u);
169+
getCentroid2(v, u);
170+
solve(centroid);
171+
}
172+
}
173+
}
174+
175+
public static void main(String[] args) throws Exception {
176+
FastReader in = new FastReader(System.in);
177+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
178+
n = in.nextInt();
179+
m = in.nextInt();
180+
for (int i = 1, u, v, w; i < n; i++) {
181+
u = in.nextInt();
182+
v = in.nextInt();
183+
w = in.nextInt();
184+
addEdge(u, v, w);
185+
addEdge(v, u, w);
186+
}
187+
for (int i = 1; i <= m; i++) {
188+
query[i] = in.nextInt();
189+
}
190+
total = n;
191+
centroid = 0;
192+
maxp[centroid] = n;
193+
// getCentroid1(1, 0);
194+
getCentroid2(1, 0);
195+
solve(centroid);
196+
for (int i = 1; i <= m; i++) {
197+
if (ans[i]) {
198+
out.println("AYE");
199+
} else {
200+
out.println("NAY");
201+
}
202+
}
203+
out.flush();
204+
out.close();
205+
}
206+
207+
// 读写工具类
208+
static class FastReader {
209+
private final byte[] buffer = new byte[1 << 16];
210+
private int ptr = 0, len = 0;
211+
private final InputStream in;
212+
213+
FastReader(InputStream in) {
214+
this.in = in;
215+
}
216+
217+
private int readByte() throws IOException {
218+
if (ptr >= len) {
219+
len = in.read(buffer);
220+
ptr = 0;
221+
if (len <= 0)
222+
return -1;
223+
}
224+
return buffer[ptr++];
225+
}
226+
227+
int nextInt() throws IOException {
228+
int c;
229+
do {
230+
c = readByte();
231+
} while (c <= ' ' && c != -1);
232+
boolean neg = false;
233+
if (c == '-') {
234+
neg = true;
235+
c = readByte();
236+
}
237+
int val = 0;
238+
while (c > ' ' && c != -1) {
239+
val = val * 10 + (c - '0');
240+
c = readByte();
241+
}
242+
return neg ? -val : val;
243+
}
244+
}
245+
246+
}
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package class183;
2+
3+
// 点分治,也叫重心分治,C++版
4+
// 测试链接 : https://www.luogu.com.cn/problem/P3806
5+
// 如下实现是C++的版本,C++版本和java版本逻辑完全一样
6+
// 提交如下代码,可以通过所有测试用例
7+
8+
//#include <bits/stdc++.h>
9+
//
10+
//using namespace std;
11+
//
12+
//const int MAXN = 10001;
13+
//const int MAXV = 20000001;
14+
//int n, m, total;
15+
//int query[MAXN];
16+
//
17+
//int head[MAXN];
18+
//int nxt[MAXN << 1];
19+
//int to[MAXN << 1];
20+
//int weight[MAXN << 1];
21+
//int cntg;
22+
//
23+
//bool vis[MAXN];
24+
//int siz[MAXN];
25+
//int maxp[MAXN];
26+
//int centroid;
27+
//
28+
//int dis[MAXN];
29+
//int valArr[MAXV];
30+
//int cntv;
31+
//int que[MAXV];
32+
//int cntq;
33+
//bool judge[MAXV];
34+
//
35+
//bool ans[MAXN];
36+
//
37+
//void addEdge(int u, int v, int w) {
38+
// nxt[++cntg] = head[u];
39+
// to[cntg] = v;
40+
// weight[cntg] = w;
41+
// head[u] = cntg;
42+
//}
43+
//
44+
//void getCentroid(int u, int fa) {
45+
// siz[u] = 1;
46+
// maxp[u] = 0;
47+
// for (int e = head[u]; e > 0; e = nxt[e]) {
48+
// int v = to[e];
49+
// if (v != fa && !vis[v]) {
50+
// getCentroid(v, u);
51+
// siz[u] += siz[v];
52+
// maxp[u] = max(maxp[u], siz[v]);
53+
// }
54+
// }
55+
// maxp[u] = max(maxp[u], total - siz[u]);
56+
// if (maxp[u] < maxp[centroid]) {
57+
// centroid = u;
58+
// }
59+
//}
60+
//
61+
//void getDistance(int u, int fa, int w) {
62+
// dis[u] = dis[fa] + w;
63+
// valArr[++cntv] = dis[u];
64+
// for (int e = head[u]; e > 0; e = nxt[e]) {
65+
// int v = to[e];
66+
// if (v != fa && !vis[v]) {
67+
// getDistance(v, u, weight[e]);
68+
// }
69+
// }
70+
//}
71+
//
72+
//void calc(int u) {
73+
// dis[u] = 0;
74+
// cntq = 0;
75+
// for (int e = head[u]; e > 0; e = nxt[e]) {
76+
// int v = to[e];
77+
// int w = weight[e];
78+
// if (!vis[v]) {
79+
// cntv = 0;
80+
// getDistance(v, u, w);
81+
// for (int k = cntv; k > 0; k--) {
82+
// for (int l = 1; l <= m; l++) {
83+
// if (query[l] >= valArr[k]) {
84+
// ans[l] |= judge[query[l] - valArr[k]];
85+
// }
86+
// }
87+
// }
88+
// for (int k = cntv; k > 0; k--) {
89+
// que[++cntq] = valArr[k];
90+
// judge[valArr[k]] = true;
91+
// }
92+
// }
93+
// }
94+
// for (int i = cntq; i > 0; i--) {
95+
// judge[que[i]] = false;
96+
// }
97+
//}
98+
//
99+
//void solve(int u) {
100+
// vis[u] = true;
101+
// judge[0] = true;
102+
// calc(u);
103+
// for (int e = head[u]; e > 0; e = nxt[e]) {
104+
// int v = to[e];
105+
// if (!vis[v]) {
106+
// total = siz[v];
107+
// centroid = 0;
108+
// maxp[centroid] = n;
109+
// getCentroid(v, u);
110+
// solve(centroid);
111+
// }
112+
// }
113+
//}
114+
//
115+
//int main() {
116+
// ios::sync_with_stdio(false);
117+
// cin.tie(nullptr);
118+
// cin >> n >> m;
119+
// for (int i = 1, u, v, w; i < n; i++) {
120+
// cin >> u >> v >> w;
121+
// addEdge(u, v, w);
122+
// addEdge(v, u, w);
123+
// }
124+
// for (int i = 1; i <= m; i++) {
125+
// cin >> query[i];
126+
// }
127+
// total = n;
128+
// centroid = 0;
129+
// maxp[centroid] = n;
130+
// getCentroid(1, 0);
131+
// solve(centroid);
132+
// for (int i = 1; i <= m; i++) {
133+
// if (ans[i]) {
134+
// cout << "AYE" << '\n';
135+
// } else {
136+
// cout << "NAY" << '\n';
137+
// }
138+
// }
139+
// return 0;
140+
//}

0 commit comments

Comments
 (0)