原本這是離散數學的期末作業,因為對圖論比較熟悉,就先看了一下圖論題;
引用《離散數學(左孝凌版)》(其實就是我們的離散數學課本……):
用韋爾奇·鮑威爾法對圖G進行着色,其方法是:
a)將圖G中的節點按照度數的遞減次序進行排列。(這種排列可能並不是唯一的,因為有些點有相同度數。)
b)用第一種顏色對第一點着色,並且按排列次序,對與前面着色點不鄰接的每一點着上同樣的顏色。
c)用第二種顏色對尚未着色的點重復b),用第三種顏色繼續這種做法,直到所有的點全部着上色為止。
然后直接照着碼成代碼即可:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define MAX 25 5 using namespace std; 6 bool edge[MAX][MAX]; 7 struct Vertex{ 8 int color,degree; 9 }vertex[MAX]; 10 int n,m;//n個點,m條邊 11 void calc_degree()//計算每個點的度數 12 { 13 for(int i=1;i<=n;i++) 14 { 15 vertex[i].color=vertex[i].degree=0; 16 for(int j=1;j<=n;j++) vertex[i].degree+=edge[i][j]; 17 } 18 } 19 bool cmp(Vertex a,Vertex b){return a.degree>b.degree;} 20 int main() 21 { 22 while(scanf("%d%d",&n,&m)!=EOF)//輸入圖的點數和邊數 23 { 24 memset(edge,0,sizeof(edge));//初始化鄰接矩陣 25 for(int i=1,u,v;i<=m;i++) 26 { 27 scanf("%d%d",&u,&v); 28 edge[u][v]=edge[v][u]=1; 29 } 30 calc_degree(); 31 sort(vertex+1,vertex+n+1,cmp); 32 int colored_vertices_cnt=0; 33 int ncolor=0; 34 while(colored_vertices_cnt<n) 35 { 36 ncolor++; 37 for(int i=1;i<=n;i++) 38 { 39 if(vertex[i].color) continue; 40 //如果已經着色就跳過 41 42 bool ok=1; 43 for(int j=1;j<=n;j++) 44 { 45 if(!edge[i][j]) continue; 46 if(vertex[j].color==ncolor) 47 { 48 ok=0; 49 break; 50 } 51 } 52 if(!ok) continue; 53 //如果鄰接的點有相同顏色就跳過 54 55 vertex[i].color=ncolor; 56 colored_vertices_cnt++; 57 printf("vertex[%d]=%d\n",i,vertex[i].color); 58 } 59 } 60 printf("%d\n",ncolor); 61 } 62 }