图着色的详细介绍请看:图着色问题 (转)
编程之美 -- 高效安排见面 也是图着色问题。
在校园招聘的季节里,为了能让学生们更好地了解微软亚洲研究院各研究组的情况,HR部门计划为每一个研究组举办一次见面会,让各个研究组的员工能跟学生相互了解和交流。已知有n位学生,他们分别对m个研究组中的若干个感兴趣。为了满足所有学生的要求,HR希望每个学生都能参加自己感兴趣的所有见面会。如果每个见面会的时间为t,那么,如何安排才能够使得所有见面会的总时间最短? 最简单的办法,就是把m个研究组的见面会时间依次排开,那我们就要用m * t的总时间,我们有10多个研究小组,时间会拖得很长,能否进一步提高效率?
(n个学生,m个研究组可以参与,同一个学生选的研究组的时间不能重合(此处略见端倪,即同一学生选的都的以不同颜色标定)。
将每个学生选的研究组用线相连,即为相邻点不能有相同颜色.从而转化为图着色问题!
以下代码为4个节点,颜色个数可以自己改变。
(可以获取最优颜色个数,以及每种的情形。)
#include <iostream>
using namespace std;
//图的描述邻接矩阵
bool is_ok(int A[][4],int n,int level,int c[]);
int trace_back(int A[][4],int n,int level,int c[],int m,int &total);
int main()
{
int A[4][4]={{0,1,1 ,0},{1,0,1,1},{1,1,0,1},{0,1,1,0}};
int c[4]={0,0,0,0};
int count(0);
int m_color;
char control_c;
//获取最优解颜色数
for(int count_i = 1;count_i <= 4;count_i++)
{
m_color = count_i;
count = trace_back(A,4,0,c,m_color,count);
if (count > 0)
{
cout<< "find the least color num!"<<endl;
cout<< "color num:"<<m_color<<endl;
break;
}
}
cout<<"---------------------------"<<endl;
//以下用于验证
do
{
count = 0;
m_color = 0;
cout<<"color num:";
cin>>m_color;
count = trace_back(A,4,0,c,m_color,count);
cout<<"total:"<<count<<endl;
cout<<"y?n :";
cin>>control_c;
}while (control_c != 'n' && control_c != 'N');
return 1;
}
bool is_ok(int A[][4],int n,int level,int c[])//验证是否相邻点颜色相同
{
for (int i = 0;i < n;i++ )
{
if (A[level][i] == 1&& c[i] ==c[level] )//邻接点颜色相同为假
{
return false;
}
}
return true;
}
//n个点m种颜色!
int trace_back(int A[][4],int n,int level,int c[],int m,int &total)
{
if(level >= n)//从0开始不要写错成>
{
total ++;
for(int i = 0; i < n;i++)
{
cout<<" "<<c[i]<<" ";
}
cout<<endl;
}
else
{
for (int j = 1;j <= m;j++)
{
c[level] = j;
if (is_ok(A, n, level, c))
{
trace_back(A, n, level+1, c, m,total);
}
c[level] = 0;//用于回溯使用!
/* 用于某一节点固定某一颜色其他剩下的颜色!
if (level == 0 && j== 1)
{
break ;
}
*/
}
}
return total;
}