diff --git a/GraphX.java b/GraphX.java new file mode 100644 index 0000000..422ef2c --- /dev/null +++ b/GraphX.java @@ -0,0 +1,120 @@ +import java.util.*; + +//****************BLACKBOX START***************** +//START COPYING FROM HERE + +class HashBox { + private final Map, Integer> map = new HashMap<>(); + private int cnt = 0; + + int hash(int x) { + return hash(new int[]{x, 0, 0}); + } + + int hash(int x, int y) { + return hash(new int[]{x, y, 0}); + } + + int hash(int x, int y, int z) { + return hash(new int[]{x, y, z}); + } + + private int hash(int[] arr) { + List key = Arrays.asList(arr[0], arr[1], arr[2]); + if (!map.containsKey(key)) { + map.put(key, cnt++); + } + return map.get(key); + } +} + +class Graph { + boolean directed; + HashBox h = new HashBox(); + + // Lazy adjacency construction for memory efficiency + Map> adj = new HashMap<>(); + + Graph(boolean directed) { + this.directed = directed; + } + + void add_edge(int uR, int vR) { + int u = h.hash(uR); + int v = h.hash(vR); + add_internal(u, v); + } + + void add_edge(int u1, int u2, int v1, int v2) { + int u = h.hash(u1, u2); + int v = h.hash(v1, v2); + add_internal(u, v); + } + + void add_edge(int u1, int u2, int u3, int v1, int v2, int v3) { + int u = h.hash(u1, u2, u3); + int v = h.hash(v1, v2, v3); + add_internal(u, v); + } + + private void add_internal(int u, int v) { + adj.computeIfAbsent(u, k -> new ArrayList<>()).add(v); + if (!directed) { + adj.computeIfAbsent(v, k -> new ArrayList<>()).add(u); + } + } +} + +class BFS { + Graph g; + Map dist = new HashMap<>(); + + BFS(Graph g) { + this.g = g; + } + + void run(int sourceR) { + int src = g.h.hash(sourceR); + run_internal(src); + } + + void run(int x, int y) { + int src = g.h.hash(x, y); + run_internal(src); + } + + void run(int x, int y, int z) { + int src = g.h.hash(x, y, z); + run_internal(src); + } + + private void run_internal(int src) { + Queue q = new ArrayDeque<>(); + q.add(src); + dist.clear(); + dist.put(src, 0); + + while (!q.isEmpty()) { + int cur = q.poll(); + for (int nxt : g.adj.getOrDefault(cur, Collections.emptyList())) { + if (!dist.containsKey(nxt)) { + dist.put(nxt, dist.get(cur) + 1); + q.add(nxt); + } + } + } + } + + int min_dist(int targetR) { + int t = g.h.hash(targetR); + return dist.getOrDefault(t, -1); + } + + boolean is_visited(int targetR) { + int t = g.h.hash(targetR); + return dist.containsKey(t); + } +} + +//END COPYING HERE +//****************BLACKBOX END****************** diff --git a/GraphX.py b/GraphX.py new file mode 100644 index 0000000..b261db7 --- /dev/null +++ b/GraphX.py @@ -0,0 +1,59 @@ +from collections import deque, defaultdict + +#****************BLACKBOX START***************** +#START COPYING FROM HERE + +class Hash: + def __init__(self): + self.mp = {} + self.cnt = 0 + + def hash(self, *args): + key = tuple(args) + (0,) * (3 - len(args)) + if key not in self.mp: + self.mp[key] = self.cnt + self.cnt += 1 + return self.mp[key] + + +class Graph: + def __init__(self, directed=True): + self.directed = directed + self.h = Hash() + self.adj = defaultdict(list) + + def add_edge(self, uR, vR): + u = self.h.hash(*uR) if isinstance(uR, tuple) else self.h.hash(uR) + v = self.h.hash(*vR) if isinstance(vR, tuple) else self.h.hash(vR) + self.adj[u].append(v) + if not self.directed: + self.adj[v].append(u) + + +class BFS: + def __init__(self, g): + self.g = g + self.dist = {} + + def run(self, sourceR): + src = self.g.h.hash(*sourceR) if isinstance(sourceR, tuple) else self.g.h.hash(sourceR) + self.dist = {src: 0} + q = deque([src]) + + while q: + cur = q.popleft() + for nxt in self.g.adj[cur]: + if nxt not in self.dist: + self.dist[nxt] = self.dist[cur] + 1 + q.append(nxt) + + def min_dist(self, targetR): + t = self.g.h.hash(*targetR) if isinstance(targetR, tuple) else self.g.h.hash(targetR) + return self.dist.get(t, -1) + + def is_visited(self, targetR): + t = self.g.h.hash(*targetR) if isinstance(targetR, tuple) else self.g.h.hash(targetR) + return t in self.dist + +#END COPYING HERE +#****************BLACKBOX END******************