圖的m色判定問題: 給定無向連通圖G和m種顏色。用這些顏色為圖G的各頂點著色.問是否存在著色方法,使得G中任2鄰接點有不同顏色。
圖的m色最佳化問題:給定無向連通圖G,為圖G的各頂點著色, 使圖中任2鄰接點著不同顏色,問最少需要幾種顏色。所需的最少顏色的數目m稱為該圖的色數。
若圖G是可平面圖,則它的色數不超過4色(4色定理).
4色定理的應用:在一個平面或球面上的任何地圖能夠只用4種
顏色來著色使得相鄰的國家在地圖上著有不同顏色
任意圖的著色
Welch Powell法
a).將G的結點按照度數遞減的次序排列.
b).用第一種顏色對第一個結點著色,並按照結點排列的次序
對與前面著色點不鄰接的每一點著以相同顏色.
c).用第二種顏色對尚未著色的點重複步驟b).用第三種顏色
繼續這種作法, 直到所有點著色完為止.
#include <fstream>#include <iostream>#include <stdlib.h>#include <algorithm>using namespacestd; int map[10][10];//鄰接矩陣 typedef structNode{ //定義節點結構體 int index; //編號 int degree; //度 int color; //改節點的顏色} Node; Nodenodes[10]; bool com(Nodenode1,Nodenode2) { //按度從高到低排序 return node1.degree > node2.degree;} bool com2(Nodenode1,Nodenode2) { //按度從高到低排序 return node1.index < node2.index;} int main() { ifstream read; read.open("map.data");//map.data是存放資料的檔案名稱 int m, n; while (read >> m>> n) { for (int i = 0; i < m; i++) {//讀入資料 int degree = 0; for (int j = 0; j < n; j++) { read>> map[i][j]; if (map[i][j]) degree++; } nodes[i].index = i; nodes[i].degree = degree; nodes[i].color = 0; } //排序 sort(nodes,nodes + m, com); int k = 0;//K 代表第幾種顏色 while (true) { k++; int i; for (i = 0; i < m; i++){//先找到第一個未著色的節點 if (nodes[i].color == 0) { nodes[i].color = k; break; } } if (i == m)//迴圈退出的條件,所有節點都已著色 break; //再把所有不和該節點相鄰的節點著相同的顏色 for(int j=0; j<m; j++){ if(nodes[j].color ==0 &&map[nodes[i].index][nodes[j].index] == 0 &&i!=j) nodes[j].color = k; } } //輸出結果: sort(nodes,nodes + m, com2);cout << "共需要" << k-1 << "種顏色" << endl; for (int i = 0; i < m; i++) cout<< "節點:"<<nodes[i].index <<":著色" << nodes[i].color <<endl; return 0; }}
測試資料(map.data):
8 8
0 1 1 1 0 0 1 0
1 0 1 1 1 0 0 0
1 1 0 0 1 1 0 0
1 1 0 0 1 0 1 0
0 1 1 1 0 1 1 1
0 0 1 0 1 0 0 1
1 0 1 1 1 0 0 1
0 0 0 0 1 1 10
即:
運行結果;
共需要3種顏色
節點:1:著色1
節點:2:著色2
節點:3:著色3
節點:4:著色3
節點:5:著色1
節點:6:著色2
節點:7:著色2
節點:8:著色3