UVa 10557 - XYZZY

題目:一個迷宮有很多個房間,以及他們的聯通關係,初始化有100的能量值,

            每進入一個房間能量值會獲得當前房間對應的能量數值(可以為負),

            如果能量為負則不能移動,房間可以反復走(對應的值可以反復獲得),

            問從1號房間出發,能否走到n號房間。

分析:圖論,最短路。利用spfa迭代求解,最後判斷到達終點的值即可。

            初始化到達所有房間時的能量值都為零,利用spfa求解到達每個房間的最大能量值即可;

            如果存在遞增的環,則迭代到上界停止即可(設為100n,從他能到達的每個點都是正的)

           (也可使用搜索嵌套求解,外層判斷是否有環以及無環時能否到達,內層判斷環能否到達終點)

說明:這個月寫的題好少╮(╯▽╰)╭。

#include <cstring>
#include <cstdio>

int energy[101];

// link_list define
typedef struct _link_list
{
	int point;
	_link_list* next;
}link_list;
link_list* link_head[105];
link_list  link_node[20202];
int  	   link_size;

void link_initial()
{
	link_size = 0;
	memset(link_head, 0, sizeof(link_head));
}

void link_insert(int a, int b)
{
	link_node[link_size].point = b;
	link_node[link_size].next = link_head[a];
	link_head[a] = &link_node[link_size ++];
}
// link_list end

int instack[105],stack[105],power[105];
int spfa(int s, int n)
{
	for (int i = 1; i <= n; ++ i)
		instack[i] = power[i] = 0;
	int top = 0, now;
	stack[top ++] = s;
	power[s] = 100;
	instack[s] = 1;
	while (top) {
		now = stack[-- top];
		for (link_list*p = link_head[now]; p; p = p->next) {
			if (power[p->point] > 100*n) continue;
			if (power[p->point] < power[now]+energy[p->point]) {
				power[p->point] = power[now]+energy[p->point];
				if (!instack[p->point]) {
					if (p->point == n) return 1;
					instack[p->point] = 1;
					stack[top ++] = p->point;
				}
			}
		}
		instack[now] = 0;
	}
	return power[n];
}

int main()
{
	int n,m,v;
	while (~scanf("%d",&n) && n != -1) {
		//读数据&建图 
		link_initial();
		for (int i = 1; i <= n; ++ i) {
			scanf("%d%d",&energy[i],&m);
			for (int j = 0; j < m; ++ j) {
				scanf("%d",&v);
				link_insert(i, v);
			}
		}
		
		if (n == 1 || spfa(1, n))
			printf("winnable\n");
		else printf("hopeless\n");
	}
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值