题目大意
一个冒险家从1号房间出发时,有100点能量值,然后题目中给出从一个房间能到达另一个房间的路,然后到达每个房间能获得的能量值(-100到100),当冒险家的能量值小于或等于0时游戏结束,然后判断是否能达到房间n;
思路
1.这题其实就是求最长路的问题;
2.首先我们用floyd算法来求各房间的连通性;
3.然后用bellman_frod算法来求解到达各房间的能量值;
code
#include <iostream> #include <fstream> #include <cstring> #include <algorithm> #include <queue> #include <vector> using namespace std; const int INF = 0x3f3f3f; struct Edge { int from, to; }; int w[105]; int dist[105], vis[105], map[105][105]; int n, eNum; Edge e[5000]; void floyd(){ for(int k = 1; k <= n; ++ k) { for(int i = 1; i <= n; ++ i) { if(map[i][k]) { for(int j = 1; j <= n; ++ j) { map[i][j] |= (map[i][k] & map[k][j]); } } } } } bool bellman_ford() { for(int i = 0; i <= n; i ++) { dist[i] = -INF; } dist[1] = 100; for(int i = 1; i < n; ++ i) { for(int j = 0; j < eNum; ++ j) { int from = e[j].from; int to = e[j].to; if(dist[to] < dist[from] + w[to] && dist[from] + w[to] > 0) { dist[to] = dist[from] + w[to]; } } } if(dist[n] > 0) { //当到达n房间的能量值为正时赢得游戏 return true; } for(int i = 0; i < eNum; ++ i) { int from = e[i].from; int to = e[i].to; //存在正环且正环上存在房间to能到达房间n if(dist[from] + w[to] > dist[to] && dist[from] + w[to] > 0 && map[to][n]) { return true; } } return false; } int main(){ std::ios::sync_with_stdio(false); std::cin.tie(0); //ifstream cin("data.in"); while(cin >> n && n != -1) { eNum = 0; memset(map, 0, sizeof(map)); for(int i = 1; i <= n; ++ i) { int num; cin >> w[i] >> num; for(int j = 0; j < num; ++ j) { int to; cin >> to; e[eNum].to= to; e[eNum++].from = i; map[i][to] = 1; } } floyd(); if(bellman_ford()) { cout << "winnable" << endl; } else{ cout << "hopeless" << endl; } } return 0; }