题目大意:有一种游戏,游戏里面有N个房间,每个房间有相应的能量值,走入该房间就可以得到相应的能量值
现在你要从房间1出发,走到房间N,如果中途能量耗尽了,就表示输了,反之,则为赢
解题思路:首先得判断一下能不能到达N,这可以用Floyd去判断
如果能直接走到N的话,就算赢,否则判断一下,看是否有正环,且正环中有点能到N
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define N 110
#define INF 0x3f3f3f3f
using namespace std;
struct Edge {
int from, to, dist;
Edge() {}
Edge(int from, int to, int dist): from(from), to(to), dist(dist){}
};
vector<Edge> edges;
bool connect[N][N];
int d[N], n;
void init() {
memset(connect, 0, sizeof(connect));
edges.clear();
int x, m, pow;
for (int i = 1; i <= n; i++) {
scanf("%d%d", &pow, &m);
for (int j = 0; j < m; j++) {
scanf("%d", &x);
edges.push_back(Edge(i, x, pow));
connect[i][x] = true;
}
}
}
void Floyd() {
for (int k = 1; k <= n; k++)
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
connect[i][j] = (connect[i][j] || (connect[i][k] && connect[k][j]));
}
bool BellmanFord() {
for (int i = 2; i <= n; i++)
d[i] = -INF;
d[1] = 100;
for (int i = 2; i <= n; i++)
for (int j = 0; j < edges.size(); j++) {
Edge &e = edges[j];
if (d[e.to] < d[e.from] + e.dist && d[e.from] + e.dist > 0) {
d[e.to] = d[e.from] + e.dist;
}
}
if (d[n] > 0)
return true;
for (int j = 0; j < edges.size(); j++) {
Edge &e = edges[j];
if (d[e.to] < d[e.from] + e.dist && d[e.from] + e.dist > 0) {
d[e.to] = d[e.from] + e.dist;
if (connect[e.to][n])
return true;
}
}
return false;
}
void solve() {
Floyd();
if (!connect[1][n] || !BellmanFord())
printf("hopeless\n");
else
printf("winnable\n");
}
int main() {
while (scanf("%d", &n) != EOF && n != -1) {
init();
solve();
}
return 0;
}