淘天 4.10 笔试
是不是我审题的问题,第一题暴力只能过0.09,40分钟死磕第三题只过了0.06,第三题到底该怎么做啊
我好像是这么写的,没法调试,也没有记录
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int m = scan.nextInt();
UF uf = new UF(n);
int u,v;
StringBuilder ans = new StringBuilder();
for (int i = 0; i < m; i++) {
u = scan.nextInt();
v = scan.nextInt();
if(uf.union(u,v)) ans.append("Yes");
else ans.append("No");
ans.append('\n');
}
System.out.println(ans);
}
}
class UF {
private int count;
private int[] parent;
private int[] size;
Set<Long> set;//记录重边
boolean[] dup;//记录重边集合
boolean[]circle;//记录有环的集合
public UF(int n) {
this.count = n;
parent = new int[n];
size = new int[n];
circle = new boolean[n];
dup = new boolean[n];
for (int i = 0; i < n; i++) {
parent[i] = i;
size[i] = 1;
}
}
public boolean union(int p, int q) {
int rootP = find(p);
int rootQ = find(q);
boolean d = set.contains(pair(p,q))||set.contains(pair(q,p))||p ==q;//重边或者自环就不能是
set.add(pair(p,q));
set.add(pair(q,p));
dup[rootP] = d;
dup[rootQ] = d;
if (rootP == rootQ) {
circle[rootP] = true;
return !dup[rootP];
}
// 平衡性优化
if (size[rootP] < size[rootQ]) {
parent[rootP] = rootQ;
size[rootQ] += size[rootP];
} else {
parent[rootQ] = rootP;
size[rootP] += size[rootQ];
}
return (circle[rootP]||circle[rootQ])&&!(dup[rootP]||dup[rootQ]);
}
private int find(int x) {
if (parent[x] != x) {
parent[x] = find(parent[x]);
}
return parent[x];
}
private long pair(int x,int y){
return ((long)x<<32)+y;
}
}
