Skip to main content

Strong Orientation

A strong orientation of an undirected graph assigns a direction to every edge so the result is strongly connected: you can go from any vertex to any other along directed edges.

This lesson follows CP-Algorithms — Strong orientation.

Related: 0-1 BFS, Centroid Decomposition.

When is it possible?​

A bridge can be crossed in only one direction after orientation, so you cannot return. Hence a graph with a bridge has no strong orientation.

Robbins' theorem: an undirected graph has a strong orientation iff it is connected and bridgeless (2-edge-connected).

Construction (DFS)​

On a bridgeless connected graph:

  1. Run DFS; build a DFS tree.
  2. Orient tree edges away from the root.
  3. Orient every other edge from descendant toward ancestor (back / cross toward the tree).

Why it works: no bridges ⇒ after deleting any tree edge you can still climb using a path with a back edge. So every vertex can reach the root, and the root can reach every vertex via the tree → strongly connected.

Minimal number of SCCs​

Orient so the digraph has as few SCCs as possible.

  • Handle each undirected component separately.
  • Bridges cannot sit inside a strong piece: after removing bridges you get bridgeless chunks you can strongly orient.
  • Orient bridges arbitrarily.

The algorithm below runs the same DFS orientation on each component: tree / back orientation plus bridge detection. Then

min #SCCs = (#undirected components) + (#bridges)

(each bridge merges into the count as an irreversible cut between otherwise strong pieces).

Implementation sketch​

Bridge-finding DFS that also records an orientation when an edge is first used:

// adj: (neighbor, edge_id); edges[id] = {a,b} as in input
// orient[id] = '>' if directed a→b, '<' if b→a
void find_bridges(int v) {
low[v] = tin[v] = time++;
for (auto [nv, id] : adj[v]) {
if (edge_used[id]) continue;
edge_used[id] = true;
orient[id] = (v == edges[id].first) ? '>' : '<';
if (tin[nv] == -1) {
find_bridges(nv);
low[v] = min(low[v], low[nv]);
if (low[nv] > tin[v]) bridge_cnt++;
} else {
low[v] = min(low[v], tin[nv]);
}
}
}
// answer: comp_cnt + bridge_cnt, and orient string

You can also orient first, then run any SCC algorithm to verify the count.

🧪 Orient a cycle vs a path

Check: strong orientation​

Quiz

Strong orientation

1 / 4

A strong orientation exists iff the graph is…

Pick an answer to see if you are right.

Practice drills​

Activity: Robbins check

Input: connected bridges as 0/1 and an integer. Print YES if a strong orientation exists (connected=1 and bridges=0), else NO.

Practice problems​

From CP-Algorithms:

Cheat sheet​

IdeaTakeaway
GoalOrient edges → strongly connected
Exists?Connected + no bridges (Robbins)
HowDFS: tree ↓ from root, backs ↑ to ancestors
Min SCCs#components + #bridges
Encode> / < vs input endpoint order