題目:一個迷宮有很多個房間,以及他們的聯通關係,初始化有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;
}