UVa 10507 - Waking up brain

题目:激活大脑,大脑分成很多个相邻的区域,如果某一区域与三个激活的区域相连时间达到一年,那么这块区域也会被激活。现在给你三块激活的区域,判断是否能够激活整个大脑,如果可以请输出激活需要的时间。

分析:搜索,最短路。激活需要的时间就是使每块被激活的时间最短,这些最小值中的最大值。虽然,初始有三个点,可以设一个原始点,进行单元最短路径算法即可;而且,由于节点间的路径长度相同,利用bfs即可。这里利用maps记录连接关系和激活关系(值为0不连通,值为1连通未激活,值为2为连通激活)。每次找到未激活节点中连接激活边大于3条的放入队列(激活)即可,因为此时一定是最早的激活时间。最后,记录最大的激活时间和判断是否所有节点都激活即可。

注意:输入和输出格式。

#include <iostream>
#include <cstdlib>
#include <cstdio>

using namespace std;

int maps[30][30];
int queue[30];
int head,tail;
int times[30];
int wake[30];
//初始化 
void init()
{
	for ( int i = 0 ; i < 26 ; ++ i )
	for ( int j = 0 ; j < 26 ; ++ j )
		maps[i][j] = maps[j][i] = 0;
	for ( int i = 0 ; i < 26 ; ++ i )
		wake[i] = 0;
	head = tail = 0;
}
//入队 
void push( int id, int t )
{
	queue[tail ++] = id;
	times[id] = t;
	wake[id] = 1;
}
//搜索 
void bfs( int n )
{
	int max_time = 0;
	while ( head < tail ) {
		int id = queue[head ++];
		int  t = times[id];
		//更新连接边的激活属性 
		for ( int i = 0 ; i < 26 ; ++ i )
			if ( maps[id][i] )
				maps[id][i] = maps[i][id] = 2;
		//判断未激活节点相连的激活边是否大于 3 
		for ( int i = 0 ; i < 26 ; ++ i ) 
			if ( !wake[i] ) {
				int sum = 0;
				for ( int j = 0 ; j < 26 ; ++ j )
					if ( i != j && maps[i][j] > 1 )
						sum ++;
				if ( sum >= 3 ) {
					push( i, t+1 );
					if ( max_time < t+1 )
						max_time = t+1;
				}
			}
	}
	
	int sum = 0;
	for ( int i = 0 ; i < 26 ; ++ i )
		if ( wake[i] ) 
			sum ++;
	if ( sum != n )
		printf("THIS BRAIN NEVER WAKES UP\n");
	else printf("WAKE UP IN, %d, YEARS\n",max_time);
}

int main()
{
	int  N,M;
	char A,B,C;
	while ( ~scanf("%d",&N) ) {
		getchar();
		scanf("%d",&M);
		getchar();
		scanf("%c%c%c",&A,&B,&C);
		getchar();
		
		init();
		push( A-'A', 0 );
		push( B-'A', 0 );
		push( C-'A', 0 );
		
		for ( int i = 0 ; i < M ; ++ i ) {
			scanf("%c%c",&A,&B);
			getchar();
			maps[A-'A'][B-'A'] = 1;
			maps[B-'A'][A-'A'] = 1;
		}
		
		bfs( N );
	}
	return 0;	
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值