闯关游戏(spfa)

闯关游戏

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <climits>
using namespace std;
const int MAXN = 110;
const int MAXM = 11000;
int p[MAXN];
bool inq[MAXN];
int d[MAXN];
int INF = INT_MIN;
int eid;
int cnt[MAXN];
int ok = 0;
int n;

struct edge {
    int v;
    int next;
    int w;
} e[MAXM];

int edgeinsert(int wei, int u, int v) {
    e[eid].v = v;
    e[eid].w = wei;
    e[eid].next = p[u];
    p[u] = eid++;
}

int init() {
    memset(p, -1, sizeof(p));
    eid = 0;
}

void SPFA(int st) {
    memset(inq, false, sizeof(inq));
    memset(d, INF, sizeof(d));
    memset(cnt, 0, sizeof(cnt));

    d[st] = 100;
    inq[st] = true;
    queue<int>q;
    q.push(st);
    cnt[st]++;//进队加1

    while(!q.empty()) {
        int u = q.front();
        q.pop();
        inq[u] = false;
        //cout << "u = " << u << ", d[u] = " << d[u] << endl;

        for(int i = p[u]; i != -1; i = e[i].next) {
            int v = e[i].v;
            //cout << "now process v = "<< v << endl;
            //cout << "now  d[u]+e[i].w = "<< d[u]+e[i].w << endl;
            //cout << "now  d[v] = "<< d[v] << endl;
            if(d[u] == INF || d[u] + e[i].w <= 0)//体力值归零
                continue;

            if(d[u] + e[i].w > d[v]) {
                //cout << "update  d[u]+e[i].w = "<< d[u]+e[i].w << endl;
                d[v] = d[u] + e[i].w;//跟新最长路
                if(!inq[v]) {
                    cnt[v]++;//进队加1
                    q.push(v);
                    inq[v] = true;
                    //cout << v << " inq" << endl;
                }
            }

            if(cnt[v] > n) { //有环,因为插入的是正权值,意味着会不停增加,肯定能到达n点
                ok = 1;
                return;
            }
        }
    }
    return;
}


int main() {
    //freopen("data.in","r",stdin);
    //freopen("data.out","w",stdout);
    ios::sync_with_stdio(false);

    init();
    cin >> n;
    for(int i = 1; i <= n; i++) {
        int w, t;
        cin>>w>>t;
        while(t--) {
            int a;
            cin>>a;
            edgeinsert(w, i, a);//注意插入的是原始权值
        }
    }

    SPFA(1);//从前向后走,求最长路

    if((d[n] != INF && d[n] > 0)||(ok == 1))
        cout<<"Yes";
    else
        cout<<"No";
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ccshijtgc/article/details/83175971