淘天 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; } }