2
public List<Integer> findAllPeople(int n, int[][] meetings, int firstPerson) {4
// create <time, index> map5
Map<Integer, List<Integer>> timeToIndexes = new TreeMap<>();6
int m = meetings.length;7
for (int i = 0; i < m; i++) {8
timeToIndexes.putIfAbsent(meetings[i][2], new ArrayList<>());9
timeToIndexes.get(meetings[i][2]).add(i);14
uf.union(0, firstPerson);16
// for every time we have a pool of people that talk to each other17
// if someone knows a secret proir to this meeting - all pool will too18
// if not - reset unions from this pool19
for (int time : timeToIndexes.keySet()) {20
Set<Integer> pool = new HashSet<>();22
for (int ind : timeToIndexes.get(time)) {23
int[] currentMeeting = meetings[ind];24
uf.union(currentMeeting[0], currentMeeting[1]);25
pool.add(currentMeeting[0]);26
pool.add(currentMeeting[1]);29
// meeting that took place now should't affect future30
// meetings if people don't know the secret31
for (int i : pool) if (!uf.connected(0, i)) uf.reset(i);34
// if the person is conneted to 0 - they know a secret35
List<Integer> ans = new ArrayList<>();36
for (int i = 0; i < n; i++) if (uf.connected(i, 0)) ans.add(i);41
private static class UF {47
for (int i = 0; i < n; i++) parent[i] = i;50
public void union(int p, int q) {54
if (rootP == rootQ) return;56
if (rank[rootP] < rank[rootQ]) {57
parent[rootP] = rootQ;59
parent[rootQ] = rootP;64
public int find(int p) {65
while (parent[p] != p) {66
p = parent[parent[p]];71
public boolean connected(int p, int q) {72
return find(p) == find(q);75
public void reset(int p) {