北邮数据结构(图的着色问题)

问题:田径会比赛安排问题

设某个田径运动会共有七个项目的比赛,分别为100米、200米、跳高、跳远、铅球、铁饼和标枪。每个选手最多参加3个项目,现有六名选手参赛,他们选择的项目如表1-1所示。考虑到每个选手的参加的各个项目不能同时进行,则如何设计合理的比赛日程,使运动会在尽可能短的时间内完成?

测试数据:

姓名

项目1

项目2

项目3

张凯

跳高

跳远

王刚

100m

200m

铁饼

李四

跳高

铅球

张三

跳远

标枪

王峰

铅球

标枪

铁饼

李杰

100m

跳远

分析:

数据预处理

首先将图中的数据用map矩阵表示出来,为着色算法做基础

具体思想见视频图着色问题(教务处怎么安排考试?)_哔哩哔哩_bilibili,讲的很清楚

着色算法

用vectro处理结点和颜色

代码如下:

#include<iostream>
#include<algorithm>
#include<vector>
using	namespace	std;

//将这7个项目编号,100米(0)、200米(1)、跳高(2)、跳远(3)、铅球(4)、铁饼(5),标枪(6) 
int	map[]=
{
	0,1,0,1,0,1,0,
	1,0,0,0,0,1,0,
	0,0,0,1,1,0,0,
	1,0,1,0,0,0,1,
	0,0,1,0,0,1,1,
	1,1,0,0,1,0,1,
	0,0,0,1,1,1,0	
}; //地图数组,存储的是各个项目之间的关系,如果两个项目不能同时举办,则标记为1 
struct	NODE
{
	int	index;//节点在map中对应的位置
	int	degree;//结点的度
	int	mark;//结点的标记 
};
bool	cmp(NODE	a,NODE	b)
{
	return	a.degree>b.degree;
}//按度数降序排列
int	fillcolor(int	map[],int	n);
void	callname(int	i);

int	main()
{
	int	n=fillcolor(map,7);
	cout<<"最少需要安排"<<n<<"场次进行比赛"<<endl;
	return	0;
}

int	fillcolor(int	map[],int	n)
{
	int	countMark=0;//记录第一个使用的颜色号 
	vector<int>mark;//颜色号集合 
	vector<NODE>node;//图中结点集合 
	node.resize(n);
	
	for(int	i=0;i<n;i++)	//统计图中每个结点的度,对map数组进行初始化 
	{
		node[i].degree=node[i].mark=0;	//度和标记初始化为0 
		node[i].index=i;	//编号
		for(int	j=0;j<n;j++)
		{
			if(map[i*n+j]==1)
				node[i].degree++;	//初始化度数	
		} 
	}
	
	sort(node.begin(),node.end(),cmp);//按照度数降序排列
	
	for(int	i=0;i<n;i++)	//从结点集中取出结点 
	{
		for(int	j=0;j<mark.size();j++)	//从颜色集中取出颜色号 
		{
			//cout<<"mark "<<mark.size()<<endl;
			if(node[node[i].index].mark==0)
				node[node[i].index].mark=mark[j];	//着色
			for(int	k=0;k<n;k++)
			{
				if(map[node[i].index*n+k]==1&&node[k].mark==node[node[i].index].mark)
				{
					node[node[i].index].mark=0;	
				}	
			} 
		}
		if(node[node[i].index].mark==0)	//新增一个色号 
		{
			mark.push_back((++countMark));
			node[node[i].index].mark=mark.back();
		}
	}
	cout<<"在第一个时间段执行的任务有";  
	for(int	i=0;i<7;i++)
	{
		if(node[i].mark==1)
		{
			callname(i); 
		}
	}
	cout<<endl;
	cout<<"在第二个时间段执行的任务有"; 
	for(int	i=0;i<7;i++)
	{
		if(node[i].mark==2)
		{
			callname(i); 
		}
	}
	cout<<endl;
	cout<<"在第三个时间段执行的任务有"; 
	for(int	i=0;i<7;i++)
	{
		if(node[i].mark==3)
		{
			callname(i);  
		}
	}
	cout<<endl;
	return	countMark;
}


//将这7个项目编号,100米(0)、200米(1)、跳高(2)、跳远(3)、铅球(4)、铁饼(5),标枪(6)
void	callname(int	i)
{
	if(i==0)
		cout<<"100米 ";
	else	if(i==1)
		cout<<"200米 ";
	else	if(i==2)
		cout<<"跳高 ";
	else	if(i==3)
		cout<<"跳远 ";
	else	if(i==4)
		cout<<"铅球 ";
	else	if(i==5)
		cout<<"铁饼 ";
	else	if(i==6)
		cout<<"标枪 ";
}




 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值