HDU - 1317 XYZZY (floyd + 最长路)

题目大意:有一种游戏,游戏里面有N个房间,每个房间有相应的能量值,走入该房间就可以得到相应的能量值
现在你要从房间1出发,走到房间N,如果中途能量耗尽了,就表示输了,反之,则为赢

解题思路:首先得判断一下能不能到达N,这可以用Floyd去判断
如果能直接走到N的话,就算赢,否则判断一下,看是否有正环,且正环中有点能到N

#include 
#include 
#include 
#include 
#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 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;
}

你可能感兴趣的:(ACM-图论-最短路)