XYZZY
大意:
模拟一个游戏,初始时有100能量,处于房间1, 现在输入n,表示有n个房间的信息,接下来n行,每行输入进入房间n的所获得的能量,以及该房间可以进入其他房间的数目;
房间可以重复进入,求出能否到达房间n,且到达每个房间时能量都大于0;
要点:
房间可以重复进入,所以能量可以达到无限;
可以判断每次到达某个房间时的能量,下一次到达该房间时如果能量大于上一次的能量,则存在正环,判断是否存在到达n的房间即可;
代码:
#include <cstdio>
#include <queue>
#include <string.h>
using namespace std;
int map[105][105], value[105], energy[105],vis[105], text;
int bfs(int x){
queue <int> que;
que.push(x);
while (!que.empty()){
for (int i = 1; i <= text; i++){
if (map[que.front()][i] && !vis[i]){
if (i == text)
return 1;
que.push(i);
vis[i] = 1;
}
}
que.pop();
}
return 0;
}
int dfs(int room, int curenergy){
if (room == text)
return 1;
else {
for (int i = 1; i <= text; i++){
if (map[room][i] && curenergy + value[i] > 0){
if (energy[i] == 0){
energy[i] = curenergy + value[i];
if (dfs(i, energy[i]))
return 1;
}
else if (curenergy + value[i] > energy[i] && bfs(i))
return 1;
}
}
}
return 0;
}
int main(){
while (scanf("%d", &text) && text != -1){
memset(map, 0, sizeof(map));
memset(value, 0, sizeof(value));
memset(energy, 0, sizeof(energy));
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= text; i++){
int num;
scanf("%d%d", &value[i], &num);
for (int j = 1; j <= num; j++){
int temp;
scanf("%d", &temp);
map[i][temp] = 1;
}
}
if (dfs(1, 100))
printf("winnable\n");
else
printf("hopeless\n");
}
return 0;
}