I need to check how many separate graphs will be created where "n rows contain pairs of positive integers, where each pair identifies a connection between two vertices in the graph.". Suppose we have 3 pairs: [4 3], [1 4], [5 6]. The answer is 2, because [4 3]&[1 4] will be merged into one graph: [1 3 4], the second one is [5 6]. If we add another pair: [4 3], [1 4], [5 6], [4 6], the answer will be 1 (only 1 graph: [1 3 4 5 6] connected). p>
I managed to solve this problem using java, but it was not efficient and was very slow for more than 10000 pairs. The code looks more or less like this:
Set<Pair> connectionsSet; HashSet<TreeSet<Integer>> createdConnections; public void createGraphs() { for (Pair pair : connectionsSet) { boolean foundLeft = false, foundRight = false; for (TreeSet<Integer> singleSet : createdConnections) { if (singleSet.contains(pair.getLeft())) foundLeft = true; if (singleSet.contains(pair.getRight())) foundRight = true; } if (!foundLeft && !foundRight) addNewGraph(pair); else if (foundLeft && !foundRight) addToExistingGraph(pair, Constants.LEFT); else if (!foundLeft && foundRight) addToExistingGraph(pair, Constants.RIGHT); else if (foundLeft && foundRight) mergeGraphs(pair); } } private void addNewGraph(Pair pair) { createdConnections.add(new TreeSet<>(pair.asList())); } private void addToExistingGraph(Pair pair, String side) { for (TreeSet<Integer> singleSet : createdConnections) { if (side.equals(Constants.LEFT) && singleSet.contains(pair.getLeft())) singleSet.add(pair.getRight()); if (side.equals(Constants.RIGHT) && singleSet.contains(pair.getRight())) singleSet.add(pair.getLeft()); } } private void mergeGraphs(Pair pair) { Optional<TreeSet<Integer>> leftSetOptional = getOptional(pair.getLeft()); Optional<TreeSet<Integer>> rightSetOptional = getOptional(pair.getRight()); if (leftSetOptional.isPresent() && rightSetOptional.isPresent()){ TreeSet<Integer> leftSet = leftSetOptional.get(); TreeSet<Integer> rightSet = rightSetOptional.get(); rightSet.addAll(leftSet); createdConnections.removeIf(singleSet -> singleSet.contains(pair.getLeft())); createdConnections.removeIf(singleSet -> singleSet.contains(pair.getRight())); createdConnections.add(rightSet); } }
How to improve performance? I'm not asking for an off-the-shelf solution, but maybe there's an algorithm I'm not aware of that would speed things up significantly?
Correct answer
To get the number of connected components you can use disjoint sets. This is a simple implementation assuming the input is a list
of edges.
map<integer, integer> parent; int find(int x) { int p = parent.getordefault(x, x); if (p != x) p = find(p); parent.put(x, p); return p; } public int numconnectedcomponents(list<pair> edges) { parent = new hashmap<>(); for (var e : edges) { int lpar = find(e.getleft()), rpar = find(e.getright()); parent.put(lpar, rpar); } int comps = 0; for (var k : parent.keyset()) if (find(k) == k) ++comps; return comps; }
If the number of nodes (n
) is known, and we can assume that all node labels are integers between 1
and n
, we can pass Optimize using arrays instead of map
and keep track of the number of connected components as edges are added.
int[] parent; int find(int x) { return x == parent[x] ? x : (parent[x] = find(parent[x])); } public int numConnectedComponents(int nodes, List<Pair> edges) { parent = new int[nodes + 1]; int comps = 0; for (var e : edges) { if (parent[e.getLeft()] == 0) { parent[e.getLeft()] = e.getLeft(); ++comps; } if (parent[e.getRight()] == 0) { parent[e.getRight()] = e.getRight(); ++comps; } int lPar = find(e.getLeft()), rPar = find(e.getRight()); if (lPar != rPar) { parent[lPar] = rPar; --comps; } } return comps; }
The above is the detailed content of Build a graph based on connected pairs of vertices. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Zend Studio 13.0.1
Powerful PHP integrated development environment

SublimeText3 English version
Recommended: Win version, supports code prompts!

Dreamweaver Mac version
Visual web development tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools