给你初始生命值100,进入房间减少或增加生命值,看能不能活着到达目的地。
开始想法是用floyd判断是否有环,然后如果没环的话用dijkstra求最长路。
有负权,问党,党说不可以用dijkstra。。。 = =。。。用了SPFA。
TLE了 = =。。我是用floyd判断是否有正环后才用SPFA的 = =。。估计这点耗时间了。
看网上大牛的思路,用SPFA判断是否有正环,如果有,再用Floyd = =。。。YM。。。
判断有环后,还要确定这个环是否能到达起始点和终点。如果到达不了还是白搭。
学到一点,我开始是,map里面存的是能量值 = =。。觉得大牛的做法比较好。。。把能量值存着。。后来加上就好。。。
#include <stdio.h> #include <stdlib.h> #include <iostream> #include <string.h> #include <queue> #include <limits.h> using namespace std; int n; int map[110][110]; int en[110]; int SPFA() { queue<int> q; int i,k,max,now,j; int used[110],dis[110],in[110]; for(i=1; i<=n; i++) dis[i] = 0; memset(in,0,sizeof(in)); memset(used,0,sizeof(used)); dis[1] = 100; used[1] = 1; q.push(1); in[1]++; while( !q.empty() ) { int x = q.front(); q.pop(); used[x] = 0; if( in[x] > n ) break; for(i=1; i<=n; i++) if( map[x][i] && dis[i] < dis[x] + en[i] ) { dis[i] = dis[x] + en[i]; if( !used[i] ) { in[i]++; used[i] = 1; q.push(i); } } } while( !q.empty() ) q.pop(); if( dis[n] > 0 ) return 1; else { for(i=1; i<=n; i++) for(j=1; j<=n; j++) for(k=1; k<=n; k++) if( map[j][i] && map[i][k] ) map[j][k] = 1; for(i=1; i<=n; i++) if( in[i] > n && map[i][n] && map[1][i] ) return 1; } return 0; } int main() { int j,k,i,m,to,ans; int tmp[110][110]; while( scanf("%d",&n) != EOF && n != -1 ) { memset(map,0,sizeof(map)); for(i=1; i<=n; i++) { scanf("%d%d",&en[i],&m); while(m--) { scanf("%d",&to); map[i][to] = 1; } } ans = SPFA(); if( ans ) printf("winnable/n"); else printf("hopeless/n"); } return 0; }