图着色

图着色的详细介绍请看:图着色问题 (

编程之美 -- 高效安排见面 也是图着色问题。

在校园招聘的季节里,为了能让学生们更好地了解微软亚洲研究院各研究组的情况,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;
}





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值