Back to Streaming Sketching

Dynamic Graph Connectivity Sketches

September 28, 2026 Wasil Zafar 13 min read

Recover spanning forests from turnstile edge streams.

Table of Contents

  1. Connectivity When Edges Arrive and Disappear
  2. Cut Sketches and Hierarchical Sampling
  3. Recovering a Spanning Forest
  4. Dynamic Networks Under Failures
  5. Trace a Connectivity Recovery

Connectivity When Edges Arrive and Disappear

A dynamic graph stream inserts and deletes undirected edges while memory is too small to store the full edge set. The goal is to recover a spanning forest: one tree per connected component. Think of islands joined by bridges. When bridges appear or disappear, we do not need every surviving bridge; we need enough certified bridges to connect every island group that remains connected.

Give every edge a canonical identity $e=(\min(u,v),\max(u,v))$. At endpoint $u$ its incidence contribution is $+e$ and at $v$ it is $-e$, where “$e$” means a coordinate in an edge-incidence vector. A deletion applies the opposite update. Linear sketches of all vertex incidence vectors can therefore be added and subtracted without replaying history.

For edges $\{(1,2),(2,3),(3,4)\}$, the cut of component $S=\{1,2\}$ contains only $(2,3)$. Adding sketches for vertices 1 and 2 cancels internal edge $(1,2)$ because its two endpoint signs oppose; $(2,3)$ survives because only endpoint 2 lies in $S$. Sampling a nonzero coordinate of that component sketch produces an outgoing edge.

Incidence vectors encode endpoint-edge relationships. A cutset $\delta(S)$ contains edges with exactly one endpoint in $S$. Hierarchical levels retain edges at geometrically decreasing rates so some level isolates one cut edge. An $L_0$-sampler returns a uniformly random nonzero coordinate or fails with bounded probability. A spanning forest preserves graph connectivity with no cycles. Linearity makes component sketches equal sums of vertex sketches. Dynamic deletions work only when edge identities, orientations, and random seeds are stable.

From dynamic edges to a cutset sampleSigned endpoint updates cancel internal edges when vertex sketches are summed, leaving an outgoing cut edge that can merge components.Dynamic graph12component S = {1,2}Sum vertex sketchesinternal: +e − e = 0cut edge surviveslevels isolate a keyRecovered witnessedge (2,3)merge componentsor report FAIL
ConceptIntuitionExact exampleNon-exampleAssumptionQuestion
Incidence vectorSigned endpoint ledgerEdge $(2,5)$ is $+1$ at 2 and $-1$ at 5Two unrelated edge encodingsCanonical orientationHow do internal edges cancel?
CutsetBoundary of a vertex set$\delta(\{1,2\})=\{(2,3)\}$All edges touching either endpointUndirected graph semanticsWhich edge can merge the component?
Hierarchical levelGeometric edge subsampleInclude with probability $2^{-j}$Fresh random choice per updateStable hash per edgeWhere is one edge isolated?
$L_0$-sampleRandom live cut coordinateReturn $(2,3)$ from a one-edge cutReturn a deleted edgeValid one-sparse certificateWhich outgoing edge is recovered?
Spanning forestConnectivity certificate$n-c$ edges for $c$ componentsA cyclic edge setRecovered edges are liveWhat output is sufficient?
LinearityAdd sketches instead of edges$\operatorname{sk}(S)=\sum_{v\in S}\operatorname{sk}(v)$Concatenate opaque summariesShared parametersHow are components queried?
Warm-up

Connectivity When Edges Arrive and Disappear

Process insertions $(1,2),(2,3),(3,4)$ and deletion $(1,2)$. The final graph has components $\{1\}$ and $\{2,3,4\}$. For $S=\{2,3\}$, edge $(2,3)$ cancels internally while $(3,4)$ remains in the cut; deleted $(1,2)$ contributes zero. Expected cutset: $\{(3,4)\}$. Reflection: what breaks if the deletion hashes $(1,2)$ with a different orientation or seed?

Cut Sketches and Hierarchical Sampling

Let $x_v$ be the signed edge-incidence vector for vertex $v$. For a component $S$, \[ x_S=\sum_{v\in S}x_v. \] Every internal edge contributes $+1-1=0$; each cut edge contributes exactly one signed nonzero. Because the sampler is linear, $\operatorname{sk}(x_S)=\sum_{v\in S}\operatorname{sk}(x_v)$ is an $L_0$-sampling sketch of the component cut.

At level $j$, retain edge $e$ when a stable hash falls below probability $2^{-j}$. If a cut has size $s$, a level with inclusion probability near $1/s$ contains exactly one cut edge with constant probability: \[ \Pr[\text{one survivor}]=sp(1-p)^{s-1}=\Theta(1). \] One-sparse moments recover and fingerprint that edge. Independent repetitions reduce failure to $\delta$. The proof obligations are stable canonical edge encoding, linear turnstile updates, sufficient hash independence, valid field/counter ranges, and randomness hidden from a nonadaptive stream.

Summing component sketches must use a snapshot of the current forest partition. A sampled edge is checked against the current disjoint-set structure; self-loops after contraction are discarded. Parallel Borůvka proposals require cycle-safe union operations. Small levels cover large cuts; dense levels cover small cuts.

Dynamic Graph Connectivity Sketches: Cut Sketches and Hierarchical Sampling
flowchart TD
 A[Canonical signed endpoint updates] --> B[Linear sketch at every vertex]
 B --> C[Sum sketches over current component]
 C --> D[Internal edges cancel]
 D --> E[Cut incidence vector remains]
 E --> F[Geometric levels isolate one cut edge]
 F --> G[Fingerprint verifies candidate]
 G --> H[Live outgoing edge merges components]
 H --> I[Repeat Boruvka rounds]
 A --> J{Encoding seed or arithmetic invalid?}
 J -->|yes| K[Cancellation or certificate fails]
 J -->|no| B
 classDef navy fill:#17365D,color:#fff,stroke:#17365D;
 classDef teal fill:#147D84,color:#fff,stroke:#0D565B;
 classDef purple fill:#6C3BAA,color:#fff,stroke:#472675;
 classDef crimson fill:#C6284D,color:#fff,stroke:#861B35;
 class A,B,C,D navy;
 class E,F,G,I purple;
 class H teal;
 class J,K crimson;
Cut cancellation and sampling levelsInternal edges cancel in the sum of component incidence sketches, while outgoing edges enter nested hash levels until one is isolated.Component sketch+e − einternal = 0; boundary survivesNested levelslevel 0: many cut edgeslevel 1: fewerlevel 2: singletonverify before returning

Linearity turns a component sum into exactly its signed cut vector; a hierarchy with a level near inverse cut size isolates an outgoing edge with constant probability, and independent repetitions amplify success. The guarantee is probabilistic and depends on stable edge identities, turnstile validity, certificate soundness, and an appropriate adversary model.

Recovering a Spanning Forest

Begin with each vertex as its own component. In one Borůvka round, query repeated cut sketches for each component, propose one verified outgoing edge, and union endpoints when they currently belong to different components. If every non-isolated component finds an edge, the number of components falls by a constant factor; $O(\log n)$ rounds suffice. Multiple independent recovery structures or carefully scheduled levels support all rounds with an overall failure budget.

Worked Example

Recovering a Spanning Forest

Use live edges $(1,2),(2,3),(1,3),(4,5),(3,4)$. Round 1 may recover $(1,2)$ for vertex 1, $(2,3)$ for 2, $(3,4)$ for 3, and $(4,5)$ for 4. Cycle-safe unions keep four edges and connect all five vertices. Delete bridge $(3,4)$ before recovery: the correct forest has components $\{1,2,3\}$ and $\{4,5\}$. An output still containing $(3,4)$ exposes broken deletion cancellation or stale decoding.

from collections import defaultdict, deque

def canonical(u, v):
    if u == v:
        raise ValueError("self-loop not allowed")
    return (u, v) if u < v else (v, u)

class DynamicGraphOracle:
    def __init__(self, vertices):
        if vertices < 1:
            raise ValueError("positive vertex count required")
        self.n = vertices
        self.counts = defaultdict(int)

    def update(self, u, v, delta):
        if not (0 <= u < self.n and 0 <= v < self.n):
            raise ValueError("vertex outside universe")
        if delta not in (-1, 1):
            raise ValueError("unit turnstile update required")
        e = canonical(u, v)
        nxt = self.counts[e] + delta
        if nxt not in (0, 1):
            raise ValueError("strict dynamic graph violated")
        self.counts[e] = nxt

    def live_edges(self):
        return sorted(e for e, count in self.counts.items() if count)

    def spanning_forest(self):
        parent = list(range(self.n))
        def find(x):
            while parent[x] != x:
                parent[x] = parent[parent[x]]
                x = parent[x]
            return x
        forest = []
        for u, v in self.live_edges():
            a, b = find(u), find(v)
            if a != b:
                parent[b] = a
                forest.append((u, v))
        return forest

    def connected(self, source, target, edges=None):
        adj = [[] for _ in range(self.n)]
        for u, v in self.live_edges() if edges is None else edges:
            adj[u].append(v); adj[v].append(u)
        seen, q = {source}, deque([source])
        while q:
            u = q.popleft()
            for v in adj[u]:
                if v not in seen:
                    seen.add(v); q.append(v)
        return target in seen

g = DynamicGraphOracle(6)
for edge in [(0,1),(1,2),(0,2),(2,3),(3,4)]:
    g.update(*edge, 1)
forest = g.spanning_forest()
assert len(forest) == 4 and g.connected(0, 4, forest)
g.update(2, 3, -1)
forest_after = g.spanning_forest()
assert not g.connected(0, 4)
assert len(forest_after) == 3

empty = DynamicGraphOracle(3)
assert empty.spanning_forest() == []
try:
    empty.update(0, 0, 1)
    raise AssertionError("self-loop accepted")
except ValueError:
    pass
try:
    empty.update(0, 1, -1)
    raise AssertionError("invalid deletion accepted")
except ValueError:
    pass

print("forest before deletion:", forest)
print("forest after bridge deletion:", forest_after)
ApproachAssumptionsSpace or timeGuaranteeStrengthFailure modePrefer when
Exact adjacency + DFSStore all live edges$O(n+m)$ spaceExact connectivitySimple oracleToo much memorySmall or moderate graphs
Dynamic forest data structureOnline access to explicit edgesImplementation-dependentExact queriesLow-latency online updatesComplex and memory-heavyRAM-resident graphs
Linear cutset sketchesTurnstile stream and stable hashesPolylogarithmic sketches per vertex/roundHigh-probability forest recoverySublinear in dense edge universeSampler failure or collisionStreaming recovery
Insertion-only union-findNo deletionsNear-linear total timeExact component queriesVery simpleCannot split after deletionMonotone graphs
Offline replayDurable update logLog-sized storage and replay timeExact final graphAuditableSlow recoveryBatch processing
Naive edge samplingRepresentative random edgesFixed sample budgetNo general connectivity guaranteeCheapMisses rare bridgesExploration, not certification

Dynamic Networks Under Failures

In a teaching case, enumerate every cut of a six-vertex graph and compare exact cut edges with summed incidence vectors. In professional network telemetry, edge coordinates may represent canonical device links; sketches from collectors merge only when universe, orientation, field, levels, repetitions, and seeds match. In an adversarial service, public seeds let clients engineer collisions, so the nonadaptive theorem no longer applies.

Invalidating evidence includes returned deleted edges, failure to cancel internal edges, forest edges forming cycles, disagreement with exact sampled audits, excessive sampler FAIL rate, arithmetic wraparound, duplicate/malformed updates, or connectivity errors concentrated on small bridge cuts.

Dynamic network connectivity pipelineCanonical edge updates enter versioned vertex sketches, recovery builds a forest, and exact audits monitor trust boundaries.Edge updatescanonical IDsinsert / deleteadaptive input riskSketch servicevertex cut sketcheslevels + repetitionsBoruvka recoverymetadata gateForest consumerconnectivityexact auditreject on drift
Dynamic Graph Connectivity Sketches: Dynamic Networks Under Failures
flowchart TD
 A[Define graph and update contract] --> B[Canonicalize edge identities]
 B --> C[Choose levels repetitions and failure budget]
 C --> D[Validate against exact dynamic graph]
 D --> E{Forest validity and recall pass?}
 E -->|yes| F[Deploy versioned sketches]
 E -->|no| G[Resize strengthen or reject]
 F --> H[Monitor deleted edges cycles and FAIL rate]
 H --> I{Threat model unchanged?}
 I -->|yes| H
 I -->|no| G
 classDef navy fill:#17365D,color:#fff,stroke:#17365D;
 classDef teal fill:#147D84,color:#fff,stroke:#0D565B;
 classDef purple fill:#6C3BAA,color:#fff,stroke:#472675;
 classDef crimson fill:#C6284D,color:#fff,stroke:#861B35;
 class A,B,C navy;
 class D,F purple;
 class E,H teal;
 class G,I crimson;
Case Study

Dynamic Networks Under Failures: Dynamic Graph Connectivity Sketches

For $n=10^7$ devices and a dense potential edge universe: define strict insertion/deletion semantics; use canonical endpoint ordering; allocate failure across levels, repetitions, components, and Borůvka rounds; validate against exact rotating subgraphs; stress bridge deletion, duplicate events, delayed updates, seed exposure, field overflow, and incompatible merges. Expected behavior is logarithmic contraction when cut samples succeed and explicit FAIL rather than fabricated edges. Deploy only if exact audits confirm live acyclic forests and the threat model protects randomness.

Trace a Connectivity Recovery

Connectivity recovery is a composition of invariants: signed incidence cancellation, valid $L_0$ certificates, and cycle-safe forest contraction.

Practice

Practice: Trace a Connectivity Recovery

Use vertices ${1,ldots,6}$ and updates inserting $(1,2),(2,3),(1,3),(3,4),(4,5)$, deleting $(1,3)$, and inserting $(5,6)$. First compute the exact final graph and components. Next write signed incidence contributions and verify internal cancellation for $S={1,2,3}$. Assign supplied hash values to four geometric levels and identify singleton cut levels. Trace union-find through two Borůvka rounds, rejecting cycles. Then break orientation, reuse update-time randomness, delete a missing edge, and fabricate a fingerprint match; name the violated invariant. Stretch: allocate total failure $delta$ across $O(log n)$ rounds and repetitions. Rubric: 25% incidence algebra, 20% level calculation, 20% forest trace, 15% deletion tests, 10% probability budget, 10% production decision.

Checklist: canonicalize edge coordinates; fix opposite endpoint signs; keep hashes stable across deletion; use certified hierarchical $L_0$ samplers; budget failure over every component and round; reject self-loops and stale/deleted candidates; union cycle-safely; version merge metadata; and audit against exact subgraphs. Do not confuse event sampling with cut sampling, union-find with deletion support, or linear incidence cancellation with negative-edge deletion. The next bridge is to dynamic spectral sparsification, cut approximation, and streaming graph analytics beyond connectivity.