Skip to content

Commit 3cfed78

Browse files
committed
modify code
1 parent 6dd32ff commit 3cfed78

File tree

4 files changed

+283
-8
lines changed

4 files changed

+283
-8
lines changed

src/class165/Code01_PersistentUnionFind1.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package class165;
22

3-
// 可持久化并查集,java版
3+
// 可持久化并查集模版题,java版
44
// 测试链接 : https://www.luogu.com.cn/problem/P3402
55
// 提交以下的code,提交时请把类名改成"Main",可以通过所有测试用例
66

@@ -79,10 +79,11 @@ public static int query(int jobi, int l, int r, int i) {
7979

8080
public static int find(int x, int v) {
8181
int fa = query(x, 1, n, rootfa[v]);
82-
if (x == fa) {
83-
return x;
82+
while (x != fa) {
83+
x = fa;
84+
fa = query(x, 1, n, rootfa[v]);
8485
}
85-
return find(fa, v);
86+
return x;
8687
}
8788

8889
public static void merge(int x, int y, int v) {

src/class165/Code01_PersistentUnionFind2.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package class165;
22

3-
// 可持久化并查集,C++版
3+
// 可持久化并查集模版题,C++版
44
// 测试链接 : https://www.luogu.com.cn/problem/P3402
55
// 如下实现是C++的版本,C++版本和java版本逻辑完全一样
66
// 提交如下代码,可以通过所有测试用例
@@ -74,10 +74,11 @@
7474
//
7575
//int find(int x, int v) {
7676
// int fa = query(x, 1, n, rootfa[v]);
77-
// if (x == fa) {
78-
// return x;
77+
// while(x != fa) {
78+
// x = fa;
79+
// fa = query(x, 1, n, rootfa[v]);
7980
// }
80-
// return find(fa, v);
81+
// return x;
8182
//}
8283
//
8384
//void merge(int x, int y, int v) {
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
package class165;
2+
3+
// 可撤销并查集模版题,java版
4+
// 测试链接 : https://www.luogu.com.cn/problem/AT_abc302_h
5+
// 测试链接 : https://atcoder.jp/contests/abc302/tasks/abc302_h
6+
// 提交以下的code,提交时请把类名改成"Main",可以通过所有测试用例
7+
8+
import java.io.BufferedReader;
9+
import java.io.IOException;
10+
import java.io.InputStreamReader;
11+
import java.io.OutputStreamWriter;
12+
import java.io.PrintWriter;
13+
import java.io.StreamTokenizer;
14+
15+
public class Code02_UndoUnionFind1 {
16+
17+
public static int MAXN = 200001;
18+
public static int[] a = new int[MAXN];
19+
public static int[] b = new int[MAXN];
20+
21+
public static int[] head = new int[MAXN];
22+
public static int[] next = new int[MAXN << 1];
23+
public static int[] to = new int[MAXN << 1];
24+
public static int cnt;
25+
26+
public static int[] father = new int[MAXN];
27+
public static int[] ncnt = new int[MAXN];
28+
public static int[] ecnt = new int[MAXN];
29+
30+
public static int[][] opstack = new int[MAXN][2];
31+
public static int stacksiz = 0;
32+
33+
public static int[] ans = new int[MAXN];
34+
public static int ball = 0;
35+
36+
public static void addEdge(int u, int v) {
37+
next[++cnt] = head[u];
38+
to[cnt] = v;
39+
head[u] = cnt;
40+
}
41+
42+
public static int find(int i) {
43+
while (i != father[i]) {
44+
i = father[i];
45+
}
46+
return i;
47+
}
48+
49+
public static void merge(int h1, int h2) {
50+
int big, small;
51+
if (ncnt[h1] >= ncnt[h2]) {
52+
big = h1;
53+
small = h2;
54+
} else {
55+
big = h2;
56+
small = h1;
57+
}
58+
stacksiz++;
59+
opstack[stacksiz][0] = big;
60+
opstack[stacksiz][1] = small;
61+
father[small] = big;
62+
ncnt[big] += ncnt[small];
63+
ecnt[big] += ecnt[small] + 1;
64+
}
65+
66+
public static void undo() {
67+
int big = opstack[stacksiz][0];
68+
int small = opstack[stacksiz][1];
69+
stacksiz--;
70+
father[small] = small;
71+
ncnt[big] -= ncnt[small];
72+
ecnt[big] -= ecnt[small] + 1;
73+
}
74+
75+
public static void dfs(int u, int fa) {
76+
int h1 = find(a[u]), h2 = find(b[u]);
77+
boolean merged = false;
78+
int add = 0;
79+
if (h1 == h2) {
80+
ecnt[h1]++;
81+
if (ncnt[h1] == ecnt[h1]) {
82+
ball++;
83+
add = 1;
84+
}
85+
} else {
86+
if (ecnt[h1] < ncnt[h1] || ecnt[h2] < ncnt[h2]) {
87+
ball++;
88+
add = 1;
89+
}
90+
merge(h1, h2);
91+
merged = true;
92+
}
93+
if (u != 1) {
94+
ans[u] = ball;
95+
}
96+
for (int e = head[u]; e > 0; e = next[e]) {
97+
if (to[e] != fa) {
98+
dfs(to[e], u);
99+
}
100+
}
101+
if (merged) {
102+
undo();
103+
} else {
104+
ecnt[h1]--;
105+
}
106+
ball -= add;
107+
}
108+
109+
public static void main(String[] args) throws IOException {
110+
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
111+
StreamTokenizer in = new StreamTokenizer(br);
112+
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
113+
in.nextToken();
114+
int n = (int) in.nval;
115+
for (int i = 1; i <= n; i++) {
116+
in.nextToken();
117+
a[i] = (int) in.nval;
118+
in.nextToken();
119+
b[i] = (int) in.nval;
120+
}
121+
for (int i = 1, u, v; i < n; i++) {
122+
in.nextToken();
123+
u = (int) in.nval;
124+
in.nextToken();
125+
v = (int) in.nval;
126+
addEdge(u, v);
127+
addEdge(v, u);
128+
}
129+
for (int i = 1; i <= n; i++) {
130+
father[i] = i;
131+
ncnt[i] = 1;
132+
ecnt[i] = 0;
133+
}
134+
dfs(1, 0);
135+
for (int i = 2; i < n; i++) {
136+
out.print(ans[i] + " ");
137+
}
138+
out.println(ans[n]);
139+
out.flush();
140+
out.close();
141+
br.close();
142+
}
143+
144+
}
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
package class165;
2+
3+
// 可撤销并查集模版题,C++版
4+
// 测试链接 : https://www.luogu.com.cn/problem/AT_abc302_h
5+
// 测试链接 : https://atcoder.jp/contests/abc302/tasks/abc302_h
6+
// 如下实现是C++的版本,C++版本和java版本逻辑完全一样
7+
// 提交如下代码,可以通过所有测试用例
8+
9+
//#include <bits/stdc++.h>
10+
//
11+
//using namespace std;
12+
//
13+
//const int MAXN = 200001;
14+
//int a[MAXN];
15+
//int b[MAXN];
16+
//
17+
//int head[MAXN];
18+
//int nxt[MAXN << 1];
19+
//int to[MAXN << 1];
20+
//int cnt;
21+
//
22+
//int father[MAXN];
23+
//int ncnt[MAXN];
24+
//int ecnt[MAXN];
25+
//
26+
//int opstack[MAXN][2];
27+
//int stacksiz = 0;
28+
//
29+
//int ans[MAXN];
30+
//int ball = 0;
31+
//
32+
//void addEdge(int u, int v) {
33+
// nxt[++cnt] = head[u];
34+
// to[cnt] = v;
35+
// head[u] = cnt;
36+
//}
37+
//
38+
//int find(int i) {
39+
// while(i != father[i]) {
40+
// i = father[i];
41+
// }
42+
// return i;
43+
//}
44+
//
45+
//void merge(int h1, int h2) {
46+
// int big, small;
47+
// if (ncnt[h1] >= ncnt[h2]) {
48+
// big = h1;
49+
// small = h2;
50+
// } else {
51+
// big = h2;
52+
// small = h1;
53+
// }
54+
// stacksiz++;
55+
// opstack[stacksiz][0] = big;
56+
// opstack[stacksiz][1] = small;
57+
// father[small] = big;
58+
// ncnt[big] += ncnt[small];
59+
// ecnt[big] += ecnt[small] + 1;
60+
//}
61+
//
62+
//void undo() {
63+
// int big = opstack[stacksiz][0];
64+
// int small = opstack[stacksiz][1];
65+
// stacksiz--;
66+
// father[small] = small;
67+
// ncnt[big] -= ncnt[small];
68+
// ecnt[big] -= ecnt[small] + 1;
69+
//}
70+
//
71+
//void dfs(int u, int fa) {
72+
// int h1 = find(a[u]), h2 = find(b[u]);
73+
// bool merged = false;
74+
// int add = 0;
75+
// if (h1 == h2) {
76+
// ecnt[h1]++;
77+
// if (ncnt[h1] == ecnt[h1]) {
78+
// ball++;
79+
// add = 1;
80+
// }
81+
// } else {
82+
// if (ecnt[h1] < ncnt[h1] || ecnt[h2] < ncnt[h2]) {
83+
// ball++;
84+
// add = 1;
85+
// }
86+
// merge(h1, h2);
87+
// merged = true;
88+
// }
89+
// if (u != 1) {
90+
// ans[u] = ball;
91+
// }
92+
// for (int e = head[u]; e > 0; e = nxt[e]) {
93+
// if (to[e] != fa) {
94+
// dfs(to[e], u);
95+
// }
96+
// }
97+
// if (merged) {
98+
// undo();
99+
// } else {
100+
// ecnt[h1]--;
101+
// }
102+
// ball -= add;
103+
//}
104+
//
105+
//int main() {
106+
// ios::sync_with_stdio(false);
107+
// cin.tie(nullptr);
108+
// int n;
109+
// cin >> n;
110+
// for (int i = 1; i <= n; i++) {
111+
// cin >> a[i] >> b[i];
112+
// }
113+
// for (int i = 1, u, v; i < n; i++) {
114+
// cin >> u >> v;
115+
// addEdge(u, v);
116+
// addEdge(v, u);
117+
// }
118+
// for (int i = 1; i <= n; i++) {
119+
// father[i] = i;
120+
// ncnt[i] = 1;
121+
// ecnt[i] = 0;
122+
// }
123+
// dfs(1, 0);
124+
// for (int i = 2; i < n; i++) {
125+
// cout << ans[i] << " ";
126+
// }
127+
// cout << ans[n] << "\n";
128+
// return 0;
129+
//}

0 commit comments

Comments
 (0)