交通指挥灯问题

交通指挥灯问题:一个具有五条通路的交叉路口,当允许某些通路上的车辆在交叉路口通行时,必须对其他通路上的车辆加以限制,不许同时在交叉路口通行,以免发生碰撞,求最少用几盏灯来指挥?

在这里插入图片描述

模型建立

1.顶点代表存在通路,如AB代表A到B路线可走
2.如果两顶点相邻,则两顶点所代表的两条路线不能同时通行,否则容易出现交通事故

算法分析

贪心算法

(1) 第一层循环,考察每一个未着色节点i;
(2) 找到一个未着色的节点i,着色。第二层循环,考察与该结点不相邻的所有结点j;
(3) 第三次循环,考察j的所有相邻节点中是否有与i涂相同颜色的节点,如果有,则j不能涂i的颜色,否则j涂i的颜色;
(4) 第二层循环结束后,当前颜色已涂完,换一种颜色,返回步骤2,继续找到一个新的i;

综上,每次考察一个外层结点,内层都要全部遍历其它结点,因而执行效率可以描述为:nnn

代码实现

//交通指挥灯问题
struct Node{//顶点类型定义 
	char name[10];//路线名称,如AB
	int color;//顶点颜色,同一颜色的顶点所代表的路线可以同时通行 
}v[13];//图中有13个顶点
int e[13][13];//1表示两顶点相邻,及两条路线不能同时通行;0相反  所以相邻顶点颜色不能相同 
int main(){
	for(int m=0;m<13;m++){
	v[m].color=0;//未着色 
	}
	//录入顶点 
	strcpy(v[0].name,"AB");strcpy(v[1].name,"AC");strcpy(v[2].name,"AD");strcpy(v[3].name,"BA");strcpy(v[4].name,"BC");
	strcpy(v[5].name,"BD");strcpy(v[6].name,"DA");strcpy(v[7].name,"DB");strcpy(v[8].name,"DC");strcpy(v[9].name,"EA");
	strcpy(v[10].name,"EB");strcpy(v[11].name,"EC");strcpy(v[12].name,"ED");
	//初始化邻接矩阵
	e[0][4]=1;e[0][5]=1;e[0][6]=1;e[0][9]=1;
	e[1][5]=1;e[1][6]=1;e[1][7]=1;e[1][9]=1;e[1][10]=1;
	e[2][9]=1;e[2][10]=1;e[2][11]=1;
	e[4][0]=1;e[4][7]=1;e[4][10]=1;
	e[5][0]=1;e[5][1]=1;e[5][6]=1;e[5][10]=1;e[5][11]=1;
	e[6][0]=1;e[6][1]=1;e[6][5]=1; e[6][10]=1; e[6][11]=1;
	e[7][1]=1;e[7][4]=1;e[7][11]=1;
	e[9][0]=1;e[9][1]=1;e[9][2]=1;
	e[10][1]=1;e[10][2]=1;e[10][4]=1;e[10][5]=1;e[10][6]=1;
	e[11][2]=1;e[11][5]=1;e[11][6]=1;e[11][7]=1;
	int cnt_color=1;//第一种颜色 
	for(int i=0;i<13;i++){//第一层循环 考察每一个未着色的点 
		int flag=1;
		if(v[i].color==0){//i点未着色 
			v[i].color=cnt_color;//着色 
			cout<<"第"<<cnt_color<<"种颜色:"<<cnt_color<<" "<<v[i].name<<" ";
			for(int j=0;j<13;j++){//第二层循环 考察所有与i点不相邻的点(这些点或许可以与i点同色) 
				if(e[i][j]==0&&v[j].color==0){//与顶点i不相邻且未着色的点j
					for(int h=0;h<13;h++){//第三层循环 考察j的所有相邻顶点,看是否与i同色 
						if(e[j][h]==1&&v[h].color==cnt_color){
							flag=0;//j不能着i的颜色,因为与它相邻的点有与i同色的 
						}
					}
					if(flag==1){//与j相邻的所有点中,没有与i同色的,j可以涂i的颜色 
						v[j].color=cnt_color;
						cout<<v[j].name<<" ";
					}
				} 
			}
			cnt_color++;//下一种颜色 
			cout<<endl;
		}
	}
	int n=cnt_color-1;
	cout<<"总共"<<n<<"种颜色";
	return 0;
}

运行结果

在这里插入图片描述
集合划分不唯一!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值