| Target | Construction |
|---|---|
| simple graph with degree sequence | Havel–Hakimi: connect the max-degree vertex to the next largest, repeat |
| bipartite graph with degree sequences | Gale–Ryser condition; greedy fill largest first |
| tree with vertices and diameter | a path of length , hang the rest on an inner vertex |
| tree with given degrees (, all ) | Prüfer-style: repeatedly join a leaf to the smallest vertex that still needs edges |
| graph with exactly shortest paths from to | binary layers: a ladder of “diamonds” doubling the count, with shortcuts for the set bits of |
| triangle-free graph with chromatic number | Mycielski construction |
| max edges without | Turán graph: near-equal parts, all edges between parts |
| strongly connected orientation | DFS tree edges downward, back edges upward (needs 2-edge-connected) |
| regular graph of degree on vertices | circulant: connect to (plus if odd, even) |
Havel–Hakimi
vector<pair<int, int>> havelHakimi(vector<int> d) { // simple graph with degrees d, or {{-1,-1}} if not graphical
int n = sz(d); vector<pair<int, int>> e;
vector<int> id(n); iota(all(id), 0);
while (true) {
sort(all(id), [&](int x, int y) { return d[x] > d[y]; });
int v = id[0]; if (d[v] == 0) break;
if (d[v] > n - 1) return {{-1, -1}};
for (int i = 1; i <= d[v]; i++) {
int u = id[i]; if (d[u] == 0) return {{-1, -1}};
d[u]--; e.push_back({v, u});
}
d[v] = 0;
}
return e;
}Proof: Havel–Hakimi is correct
Let have maximum degree . Claim: if is graphical, there is a realization in which is adjacent to the vertices of largest remaining degree. Take any realization; if is adjacent to but not to with (or equal and preferred), then has a neighbour not adjacent to (since has more neighbours outside than does). Replace edges by : degrees are unchanged, and ‘s neighbourhood improved. Repeating gives the claim. Removing and decrementing its neighbours leaves a graphical sequence iff the original was graphical, so the greedy succeeds exactly on graphical sequences. Verified against all graphs on vertices.
Tree with a given diameter
vector<pair<int, int>> treeWithDiameter(int n, int d) { // vertices 0..n-1; exists iff 1 <= d <= n-1 and (d >= 2 or n == 2)
if (d < 1 || d > n - 1 || (d == 1 && n > 2)) return {};
vector<pair<int, int>> e;
for (int i = 0; i < d; i++) e.push_back({i, i + 1}); // the diameter path 0..d
for (int v = d + 1; v < n; v++) e.push_back({1, v}); // hang the rest on vertex 1 (not an end)
return e;
}Proof: the diameter stays d
The path has length . A hung vertex is at distance from vertex , so its distance to any path vertex is (since ), and two hung vertices are at distance . A tree on vertices has a vertex of degree , so its diameter is at least , which is why only works for . Verified by BFS for all .
Related: Special Graphs, Prüfer Codes.