#include <iostream> #include <cstring> using namespace std; #define N 8 //表示一张图 int g[][N]={ {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,1,0} }; //标记的颜色 int color[N]; //检查是否有邻居标记过同一种颜色 int ok(int t){ for(int i=0;i<N;i++) if(i!=t&&g[t][i]&&color[t]==color[i]) return 0; return 1; } //试着用m种颜色进行标记 bool traceback(int t,int m){ if(t>=N)return true; for(int i=1;i<=m;i++){ color[t]=i; if(ok(t)&&traceback(t+1,m))return true; color[t]=0; } return false; } int main() { #ifndef wangchuan freopen("C:\\in.txt","r",stdin); #endif // !wangchuan memset(color,0,sizeof(color)); for(int j=1;j<=4;j++){ if(traceback(0,j)){ for(int i=0;i<N;i++){ cout<<"第"<<i<<"点标记颜色"<<color[i]<<endl; } break; } } return 0; } |
a).将G的结点按照度数递减的次序排列.
b).用第一种颜色对第一个结点着色,并按照结点排列的次序
对与前面着色点不邻接的每一点着以相同颜色.
c).用第二种颜色对尚未着色的点重复步骤b).用第三种颜色
继续这种作法, 直到所有点着色完为止.
//图着色问题 //WelchPowell法 #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define N 8 //表示一张图 int g[][N]={ {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,1,0} }; struct node{ int color;//标记的颜色 int degree;//节点的度数(出度或入度) int index;//因为要排序,所以先要记录节点所在位置 bool operator<(node &t){ return degree>t.degree; } }Node[N]; void WelchPowell(){ sort(Node,Node+N); int k = 0;//K 代表第几种颜色 while (true) { k++; int i; for (i = 0; i < N; i++){//先找到第一个未着色的节点 if (Node[i].color == 0) { Node[i].color = k; break; } } if (i == N)//循环退出的条件,所有节点都已着色 break; //再把所有不和该节点相邻的节点着相同的颜色 for(int j=0; j<N; j++){ if(Node[j].color ==0 &&g[Node[i].index][Node[j].index] == 0&&i!=j) Node[j].color = k; } } } int main() { #ifndef WANGCHUAN freopen("C:\\in.txt","r",stdin); #endif // !WANGCHUAN for(int i=0;i<N;i++){ Node[i].index=i; Node[i].color=0; Node[i].degree=0; for(int j=0;j<N;j++){ if(g[i][j])Node[i].degree++; } } WelchPowell(); for (int i=0; i<N; i++) cout<<"第"<<Node[i].index<<"点标记颜色"<< Node[i].color <<endl; return 0; } |
//图着色问题 //贪心法 #include <iostream> #include <cstring> #include <algorithm> using namespace std; #define N 8 //表示一张图 int g[][N]={ {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,1,0} }; int color[N]; //检查是否有邻居标记过颜色k int ok(int t,int k){ for(int i=0;i<N;i++) if(i!=t&&g[t][i]&&k==color[i]) return 0; return 1; } void Greedy(){ color[0]=1;//先给节点0着颜色1 int k = 0;//K 代表第几种颜色 while (true) { k++; //如果所有顶点均着色,退出循环 int i; for(i=1;i<N;i++)if(!color[i])break; if(i==N)break; // for(int i=1;i<N;i++){ if(color[i])continue; //判断i点能否着颜色k,即i的邻居节点没有着颜色k的 if(ok(i,k))color[i]=k; } } } int main() { #ifndef WANGCHUAN freopen("C:\\in.txt","r",stdin); #endif // !WANGCHUAN memset(color,0,sizeof(color)); Greedy(); for (int i=0; i<N; i++) cout<<"第"<<i<<"点标记颜色"<< color[i] <<endl; return 0; } |
原文:http://blog.csdn.net/starcuan/article/details/19367383