Graph Coloring

Vertex Coloring

(The discussion concerns simple undirected graphs without self-loops.)

Color the vertices of an undirected graph so that adjacent vertices have different colors. If G is kk-colorable but not (k−1)(k-1)-colorable, then k is the chromatic number of G, denoted by χ(G)\chi(G).

For every graph G, χ(G)≤Δ(G)+1\chi(G) \leq \Delta(G) + 1, where Δ(G)\Delta(G) is the maximum degree.

Brooks's Theorem

Suppose the connected graph is neither complete nor an odd cycle. Then χ(G)≤Δ(G)\chi(G) \leq \Delta(G).

Proof

Proof

Let ∣V(G)∣=n|V(G)|=n, and use mathematical induction.

For n≤3n\leq 3, the claim is obvious.

Now assume that the claim holds for n−1n-1; we will strengthen the claim step by step.

We may restrict attention to Δ(G)\Delta(G)-regular graphs, because a nonregular graph can be viewed as a regular graph with some edges deleted, and this process does not affect the conclusion.

For any regular graph G that is neither complete nor an odd cycle, choose a vertex v and consider the subgraph H:=G−vH:=G-v. By the induction hypothesis, χ(H)≤Δ(H)=Δ(G)\chi(H)\leq\Delta(H)=\Delta(G); it remains only to prove that inserting v into H does not affect the conclusion.

Let Δ:=Δ(G)\Delta:=\Delta(G). Suppose H is colored with Δ\Delta colors c1,c2,…,cΔc_1,c_2,\dots,c_{\Delta}, and let the Δ\Delta neighbors of v be v1,v1,…,vΔv_1,v_1,\dots,v_{\Delta}. We may assume that these neighbors of v have pairwise distinct colors; otherwise the claim is proved.

Now let the vertices of H colored cic_i or cjc_j, together with all edges between them, form the subgraph Hi,jH_{i,j}. We may assume that any two distinct vertices viv_i and vjv_j lie in the same connected component of Hi,jH_{i,j}; otherwise, if they lay in different components, we could swap the colors of every vertex in one component, making viv_i and vjv_j have the same color.

Here, swapping colors means that if a graph uses only two colors a and b, every vertex originally colored a is recolored b, and every vertex originally colored b is recolored a.

Let the component above be Ci,jC_{i,j}. Then Ci,jC_{i,j} can only be a path from viv_i to vjv_j. Since viv_i has degree Δ−1\Delta-1 in H, the colors of the neighbors of viv_i in H must all be distinct; otherwise we could give viv_i another color, causing a duplicate with the colors of v's other neighbors. Therefore, viv_i has exactly one neighbor in Ci,jC_{i,j}, and vjv_j is analogous. We then take a path in Ci,jC_{i,j} from viv_i to vjv_j and call it P. If Ci,j≠PC_{i,j}\ne P, we can recolor the vertices along P in order. Let u be the first vertex encountered whose degree is greater than 2. Its neighbors use at most Δ−2\Delta-2 colors, so u can be recolored, making viv_i and vjv_j disconnected.

It is then easy to see that for any three distinct vertices viv_i, vjv_j, and vkv_k, V(Ci,j)∩V(Cj,k)={vj}V(C_{i,j})\cap V(C_{j,k})=\{v_j\}.

The strengthening of the claim is now complete.

The rest is simple. If the neighbors of v are pairwise adjacent, the claim is proved. Otherwise, suppose v1v_1 and v2v_2 are not adjacent. In C1,2C_{1,2}, take the neighbor v1v_1 of w and swap the colors in C1,3C_{1,3}. In the resulting graph, w∈V(C1,2)∩V(C2,3)w\in V(C_{1,2})\cap V(C_{2,3}), a contradiction.

This proves the claim.

Welsh–Powell Algorithm

The Welsh–Powell algorithm is a greedy algorithm for finding a coloring when the maximum number of colors is not restricted.

For a simple undirected graph G without self-loops, let V(G):={v1,v2,…,vn}V(G):=\{v_1,v_2,\dots,v_n\} satisfy.

deg⁡(vi)≥deg⁡(vi+1), ∀1≤i≤n−1\deg(v_i)\geq\deg(v_{i+1}),~\forall 1\leq i\leq n-1

The Welsh–Powell algorithm uses at most max⁡i=1nmin⁡{deg⁡(vi)+1,i}\max_{i=1}^n\min\{\deg(v_i)+1,i\} colors, and its time complexity is O(nmax⁡i=1nmin⁡{deg⁡(vi)+1,i})=O(n2)O\left(n\max_{i=1}^n\min\{\deg(v_i)+1,i\}\right)=O(n^2).

Procedure

  1. Sort the currently uncolored vertices in descending order of degree.
  2. Color the first vertex with an unused color.
  3. Traverse the remaining vertices in order. If the current vertex is not adjacent to any vertex with the same color as the first vertex, color it with that same color.
  4. If uncolored vertices remain, return to step 1; otherwise, finish.

An example follows:

Original
Original

(Generated by Graph Editor.)

First sort the vertices in descending order of degree:

Order12345678910111213
Vertex number4502913610127811
Degree5544433333221
min⁡{deg⁡(vi)+1,i}\min\{\deg(v_i)+1,i\}1234544444332

Thus the Welsh–Powell algorithm uses at most 5 colors.

Moreover, because this graph contains the subgraph C3C_3, its chromatic number is at least 3.

  • First coloring:

    Colored 1
    Colored 1

    Color vertices 4 9 3 11.

  • Second coloring:

    Colored 2
    Colored 2

    Color vertices 5 2 6 7 8.

  • Third coloring:

    Colored 3
    Colored 3

    Color vertices 0 1 10 12.

Proof

Proof

For a simple undirected graph G without self-loops, let V(G):={v1,v2,…,vn}V(G):=\{v_1,v_2,\dots,v_n\} satisfy

deg⁡(vi)≥deg⁡(vi+1), ∀1≤i≤n−1\deg(v_i)\geq\deg(v_{i+1}),~\forall 1\leq i\leq n-1

Set V0=∅V_0=\varnothing. From V(G)∖⋃i=0m−1ViV(G)\setminus\bigcup_{i=0}^{m-1} V_i, choose a subset VmV_m whose elements satisfy

  1. vkm∈Vmv_{k_m}\in V_m, where km=min⁡{k:vk∉⋃i=0m−1Vi}k_m=\min\{k:v_k\notin\bigcup_{i=0}^{m-1} V_i\}.

  2. If

    {vim,1,vim,2,…,vim,lm}⊂Vm, im,1<im,2<⋯<im,lm\{v_{i_{m,1}},v_{i_{m,2}},\dots,v_{i_{m,l_m}}\}\subset V_m,~i_{m,1}<i_{m,2}<\dots<i_{m,l_m}

    then vj∈Vmv_j\in V_m if and only if both

    1. j>im,lmj>i_{m,l_m};
    2. vjv_j is not adjacent to any of vim,1,vim,2,…,vim,lmv_{i_{m,1}},v_{i_{m,2}},\dots,v_{i_{m,l_m}}.

Clearly, coloring the vertices in ViV_i with color i gives exactly the coloring produced by the Welsh–Powell algorithm. Clearly,

  • V1≠∅V_1\neq\varnothing;
  • Vi∩Vj=∅  ⟺  i≠jV_i\cap V_j=\varnothing\iff i\neq j;
  • ∃α(G)∈N∗,∀i>α(G), s.t. Vi=∅\exists \alpha(G)\in\Bbb{N}^*,\forall i>\alpha(G),~s.t.~ V_i=\varnothing.

We only need to prove

⋃i=1α(G)Vi=V(G)\bigcup_{i=1}^{\alpha(G)} V_i=V(G)

where

χ(G)≤α(G)≤max⁡i=1nmin⁡{deg⁡(vi)+1,i}\chi(G)\leq\alpha(G)\leq\max_{i=1}^n\min\{\deg(v_i)+1,i\}.

The inequality on the left is obvious; consider the right-hand inequality.

First, we readily obtain the following:

If v∉⋃i=1mViv\notin\bigcup_{i=1}^mV_i, then v is adjacent to at least one vertex in each of V1,V2,…,VmV_1,V_2,\dots,V_m, and therefore deg⁡(v)≥m\deg(v)\geq m.

Consequently,

vj∈⋃i=1deg⁡(vj)+1Viv_j\in\bigcup_{i=1}^{\deg(v_j)+1}V_i.

On the other hand, from the construction of the sequence {Vi}\{V_i\}, we readily see that

vj∈⋃i=1jViv_j\in\bigcup_{i=1}^j V_i.

Combining the two relations proves the result.

Edge Coloring

For an undirected graph, edge coloring requires adjacent edges to receive different colors. If G is k-edge-colorable but not (k−1)(k-1)-edge-colorable, k is called the edge-chromatic number of G, denoted by χ′(G)\chi'(G).

Vizing's Theorem

If G is a simple graph, then Δ(G)≤χ′(G)≤Δ(G)+1\Delta(G) \leq \chi'(G) \leq \Delta(G) + 1.

If G is bipartite, then χ′(G)=Δ(G)\chi'(G)=\Delta(G).

When nn is odd (n≠1n \neq 1), χ′(Kn)=n\chi'(K_n)=n; when nn is even, χ′(Kn)=n−1\chi'(K_n)=n-1.

Constructive Proof of Vizing's Theorem for Bipartite Graphs

Proof

Add edges to the bipartite graph in order.

When trying to add the edge (x,y)(x,y), look for the smallest-numbered unused color at xx and yy, and suppose these colors are lxl_x and lyl_y, respectively.

If lx=lyl_x=l_y, we can directly assign lxl_x to this edge.

Otherwise, suppose lx<lyl_x<l_y. We can try to change the color of the edge incident to vertex yy whose color is lxl_x to lyl_y.

This process can be viewed approximately as a finite unique augmenting path starting at yy and successively traversing edges with colors lx,ly,⋯l_x,l_y,\cdots.

Since the augmenting path is finite, we can swap the colors of all its edges: edges originally colored lxl_x are changed to lyl_y, and edges originally colored lyl_y are changed to lxl_x.

By the bipartite-graph property, vertex xx cannot be a vertex on the augmenting path; otherwise the smallest unused color would be lxl_x, a contradiction.

Thus, after the augmentation, we can assign the color of the edge connecting xx and yy to lxl_x.

The total construction time complexity is O(nm)O(nm).

Example Code: UVa10615 Rooks
#include <iostream>

constexpr int MAXN = 100;

int t;
int n;
char a[MAXN + 10][MAXN + 10];
int c[MAXN + 10][MAXN + 10];
int ans;

namespace graph {
struct Vertex {
  int head;
  int deg;
  int vis[MAXN + 10];
} vertex[2 * MAXN + 10], e;

struct Edge {
  int head;
  int next;
  int col;
} edge[2 * MAXN * MAXN + 10];

int ecnt;

void init() {
  for (int i = 0; i < MAXN + 10; i++) std::fill(c[i], c[i] + MAXN + 10, 0);
  for (int i = 1; i <= 2 * MAXN; i++) vertex[i] = e;
  for (int i = 0; i <= 2 * MAXN * MAXN; i++) edge[i].col = 0;
  ecnt = 1;
  ans = 0;
  return;
}

void addEdge(int tail, int head) {
  ecnt++;
  edge[ecnt].head = head;
  edge[ecnt].next = vertex[tail].head;
  vertex[tail].head = ecnt;
  vertex[tail].deg++;
  return;
}

int get(int u) {
  for (int i = 1; i <= n; i++)
    if (!vertex[u].vis[i]) return i;
  exit(1);
}

void DFS(int u, int ori, int upd) {
  if (vertex[u].vis[ori] == 0) {
    vertex[u].vis[upd] = 0;
    return;
  }
  int e = vertex[u].vis[ori];
  int v = edge[e].head;
  DFS(v, upd, ori);
  edge[e].col = upd;
  edge[e ^ 1].col = upd;
  vertex[u].vis[upd] = e;
  vertex[v].vis[upd] = e ^ 1;
  return;
}

void AddEdge(int u, int v) {
  addEdge(u, v);
  addEdge(v, u);
  return;
}

void solve() {
  for (int u = 1; u <= n; u++) {
    for (int e = vertex[u].head; e; e = edge[e].next) {
      int v = edge[e].head;
      if (edge[e].col) continue;
      int lu = get(u);
      int lv = get(v);
      if (lu < lv) DFS(v, lu, lv);
      if (lu > lv) DFS(u, lv, lu);
      int l = std::min(lu, lv);
      vertex[u].vis[l] = e;
      vertex[v].vis[l] = e ^ 1;
      edge[e].col = l;
      edge[e ^ 1].col = l;
    }
  }
}

void generate() {
  for (int u = 1; u <= n; u++) {
    for (int e = vertex[u].head; e; e = edge[e].next) {
      int v = edge[e].head;
      c[u][v - n] = edge[e].col;
    }
  }
  return;
}
}  // namespace graph

void mian() {
  graph::init();
  std::cin >> n;
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) std::cin >> a[i][j];
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
      if (a[i][j] == '*') graph::AddEdge(i, j + n);
  for (int i = 1; i <= n * 2; i++) ans = std::max(ans, graph::vertex[i].deg);
  graph::solve();
  graph::generate();
  std::cout << ans << '\n';
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) std::cout << c[i][j] << ' ';
    std::cout << '\n';
  }
  return;
}

int main() {
  std::cin >> t;
  while (t--) mian();
  return 0;
}
A Challenging Example: UOJ 444 Bipartite Graph

The author created this problem as an assignment for the first round of the training team in 2018.

First, we can observe that the lower bound on the answer is the number of vertices whose degree is not a multiple of k.

The lower-bound construction splits vertices in the bipartite graph.

If degree mod k≠0degree \bmod k \neq 0, split the vertex into degree/kdegree/k vertices of degree k and one vertex of degree degree mod kdegree \bmod k.

If degree mod k=0degree \bmod k = 0, split it into degree/kdegree/k vertices of degree k.

The split vertices have the same meaning as the original vertex, so under the degree constraint, an edge endpoint may be connected to any one of the split vertices.

By Vizing's theorem, we can clearly construct a k-coloring of the resulting graph.

The edge-deletion part is not closely related to Vizing's theorem, so it is omitted here.

Interested readers may read the solution written by the author at the time.

The Chromatic Polynomial

P(G,k)P(G,k) denotes the total number of distinct k-colorings of G.

P(Kn,k)=k(k−1)⋯(k−n+1)P(K_n, k) = k(k-1)\cdots(k-n+1)

P(Nn,k)=knP(N_n, k) = k^n

For a simple undirected graph G,

  1. If e=(vi,vj)∉E(G)e=(v_i, v_j) \notin E(G), then P(G,k)=P(G∪e,k)+P(G∖e,k)P(G, k) = P(G \cup e, k)+P(G\setminus e, k).
  2. If e=(vi,vj)∈E(G)e=(v_i, v_j) \in E(G), then P(G,k)=P(G−e,k)−P(G∖e,k)P(G,k)=P(G-e,k)-P(G\setminus e,k).

Theorem: Let V1V_1 be a vertex cut set of G, let G[V1]G[V_1] be a complete subgraph of G with ∣V1∣|V_1| vertices, and suppose G−V1G-V_1 has p(p≥2)p(p \geq 2) connected components. Then

P(G,k)=Πi=1p(P(Hi,k))P(G[V1],k)p−1P(G,k)=\frac{\Pi_{i=1}^{p}{(P(H_i, k))}}{P(G[V_1], k)^{p-1}}

where Hi=G[V1∪V(Gi)]H_i=G[V_1 \cup V(G_i)].

References

  1. Graph coloring - Wikipedia
  2. Welsh, D. J. A.; Powell, M. B. (1967), "An upper bound for the chromatic number of a graph and its application to timetabling problems", The Computer Journal, 10 (1): 85–86

This content comes from OI Wiki: Graph Coloring. See the original for authors and revision history. AIOJ has adapted the formatting, in-site links, and resource paths.

Content is shared under CC BY-SA 4.0 and SATA license; additional terms are governed by the original notice. Thanks to the OI Wiki authors and contributors; per the SATA terms, please visit the OI Wiki repository and star it to show your support.