题意
有 个屋子,走进每个屋子血量都会发生改变,开始生命值 。问是否可以从 号屋子走到 号屋子中间血量保持大于
思路
- 按照给定的顺序建图,因为要让血量尽可能的高所以求最长路,如果走到 的最长路的血量小于0那么就无解。
- 最长路可能存在正环,当存在正环而且 到 联通,那么一定有解
- 个人认为标程应该是 判正环+传递闭包判联通,网上有人是判断存在正环之后把 赋值为 最后判断dis[n] > 0,这样其实不对,把 置为 不一定能更新到 ,可以测下这个数据。
5
0 1 2
1 1 3
2 1 4
3 2 2 5
-1061109567 0
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <vector>
#include <stdio.h>
#include <iostream>
#include <numeric>
#include <algorithm>
#include <cstring>
#include <time.h>
#define LL long long
#define P pair<int, int>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define mid ((l + r) >> 1)
#define lc rt<<1
#define rc rt<<1|1
#define endl '\n'
const int maxn = 1e2 + 5;
const int inf = 0x3f3f3f3f;
const int mod = 1e9 + 7;
using namespace std;
vector<int> g[maxn];
int dis[maxn], vis[maxn], cnt[maxn], val[maxn];
int mp[maxn][maxn];
int n;
int Spfa(int s, int e) {
for (int i = 1; i <= e; ++i) {
dis[i] = -inf;
}
mem(vis, 0);
mem(cnt, 0);
vis[s] = 1;
cnt[s] = 1;
dis[s] = 100;
queue<int> que;
que.push(s);
while (!que.empty()) {
int f = que.front();
que.pop();
vis[f] = 0;
if (cnt[f] >= n) dis[f] = inf;
int len = g[f].size();
for (int i = 0; i < len; ++i) {
int t = g[f][i];
if (dis[t] < dis[f] + val[t] && dis[f] + val[t] > 0) {
dis[t] = dis[f] + val[t];
if (vis[t] == 0 && ++cnt[t] <= n) {
vis[t] = 1;
que.push(t);
}
if (cnt[t] > e) return -1;
}
}
}
return dis[e] > 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
while (scanf("%d", &n) != EOF) {
mem(mp, 0);
if (n == -1) break;
for (int i = 0; i <= n; ++i) g[i].clear();
int num, d;
for (int i = 1; i <= n; ++i) {
scanf("%d%d", &val[i], &num);
for (int j = 0; j < num; ++j) {
scanf("%d", &d);
g[i].push_back(d);
mp[i][d] = 1;
}
}
int ans = Spfa(1, n);
if (ans == -1){
for (int k = 1; k <= n; ++k) {
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
if (mp[i][k] && mp[k][j]) mp[i][j] = 1;
}
}
}
for (int i = 1; i <= n; ++i) {
if (mp[1][i] && mp[i][n] && cnt[i] > n) {
ans = 1;
break;
}
}
}
if (ans == 1) puts("winnable");
else puts("hopeless");
}
return 0;
}