题意:
打游戏..从1出发初始100的血...经过每个点就会加一定的血或者扣一定的血...若血量<=0了..就挂了..问能不能活着到达点N...
题解:
相当于用SPFA求最远距离了..那么注意的就是出现正环的情况..从环上的点dfs一次看能到到达点N..若可以..直接返回true..否则..继续往下找...
Program:
#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
#define MAXN 1205
#define MAXM 8000005
#define oo 1000000007
#define ll long long
using namespace std;
bool A[105][105],F[105],InQ[105];
int C[105],times[105],dp[105];
void dfs(int x,int n)
{
F[x]=true;
for (int i=1;i<=n;i++)
if (!F[i] && A[x][i]) dfs(i,n);
}
bool judge(int n)
{
int x,i;
queue<int> Q;
memset(dp,-0x2f,sizeof(dp));
memset(times,0,sizeof(times));
memset(InQ,false,sizeof(InQ));
Q.push(1),dp[1]=100;
while (!Q.empty())
{
x=Q.front(),Q.pop();
times[x]++,InQ[x]=false;
if (times[x]>n)
{
memset(F,false,sizeof(F)),dfs(x,n);
if (F[n]) return true;
continue;
}
for (i=1;i<=n;i++)
if (A[x][i] && dp[x]+C[i]>0 && dp[i]<dp[x]+C[i])
{
dp[i]=dp[x]+C[i];
if (!InQ[i]) InQ[i]=true,Q.push(i);
}
}
return dp[n]>0;
}
int main()
{
int n,s,e,i,x,m;
while (~scanf("%d",&n) && n>=0)
{
memset(A,false,sizeof(A));
for (i=1;i<=n;i++)
{
scanf("%d%d",&C[i],&m);
while (m--) scanf("%d",&x),A[i][x]=true;
}
if (judge(n)) printf("winnable\n");
else printf("hopeless\n");
}
return 0;
}