#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