关于图的N可着色问题

来源:互联网 发布:网络基础设施安全 编辑:程序博客网 时间:2024/05/22 18:56

关于图的N可着色(对于一个给定的一个图,对每个顶点逐一着色,使得图中每一条边的两个顶点的颜色都不一样)大家都知道是NP问题。

下面我们可以考虑使用递归来解决这个问题

算法:

递归的增量是当前的节点的下标v,递归结束的条件是v大于等于图中节点的数量。每次递归结束的时候可以打印出对应的着色情况。每次递归到下个节点需要逐个尝试染上各种颜色。最后每次递归调用返回的时候需要将这一层递归对应的节点的颜色涂为default值。这样就可以顺利实现这个问题。

数据结构:

1. 可以使用邻接矩阵来求解,不过实现非常简单,这里不多介绍。

2. 使用邻接表来求解,数据结构是这样的。Vertice类型代表邻接表中头结点的后续节点,对于有向图来讲就是Vertice节点就是边的目的节点,主要成员是节点的ID和下一节点的地址。而头结点是AdVertice类型,主要成员是一个指向下一个Vertice节点的指针。

代码

#include <iostream>
using namespace std;


#define N 10
//临界表中的dest节点
struct Vertice{
int ID;
Vertice *next;
};


//临界表头结点
struct AdVertice{
Vertice *next;
};


struct Graph{
AdVertice ver[N];//头结点数组
int vertices;
int edges;
bool Visited[N];
int color[N];
};


void update_front(Graph *g,int v1,int v2){
Vertice *New = new Vertice;
New->ID = v2;
New->next = g->ver[v1].next;
g->ver[v1].next = New;

}

int colorable(Graph *g,int v){
Vertice *current = g->ver[v].next;
while(current!=NULL){
int id = current->ID;
if(g->color[id]==g->color[v])
return 0;
current = current->next;
}
return 1;
}

//N着色问题
void dfs_colorable(Graph *g,int v,int vertices,int colors){
if(v>=vertices){
for(int j = 0;j<vertices;j++)
cout<<g->color[j]<<"";
cout<<endl;
return;
}
for(int i = 0;i<colors;i++){
g->color[v] = i;
if(colorable(g,v)==1){
//cout<<"v:"<<v<<endl;
dfs_colorable(g,v+1,vertices,colors);
}
}
//reset
g->color[v] = -1;
return ;
}


void update(Graph *g,int v1,int v2){
update_front(g,v1,v2);
update_front(g,v2,v1);
}


void print_edges(Graph *g){
for(int i = 0;i<N;i++){
Vertice *current = g->ver[i].next;

while(current!=NULL){
current = current->next;
}
cout<<endl;
}
}
int main(){


int num_of_vertices = 0;
cout<<"pls input the num of the vertices"<<endl;
cin>>num_of_vertices;

int num_of_edges = 0;
cout<<"pls input the num of the edges"<<endl;
cin>>num_of_edges;

int colors = 0;
cout<<"pls input the num of colors"<<endl;
cin>>colors;

Graph *g = new Graph;
g->vertices = num_of_vertices;
g->edges = num_of_edges;

for(int j = 0;j<N;j++){
g->ver[j].next = NULL;
g->color[j] = -1;
}

for(int i=0;i<num_of_edges;i++){
int v1=0;
int v2 = 0;
cin>>v1>>v2;
update(g,v1,v2);
}
//print_edges(g);
int v = 0;
dfs_colorable(g,v,num_of_vertices,colors);
}