HDOJ 1317 - XYZZY dp(SPFA)+dfs判联通..细心..

本文探讨了一款游戏中的生存策略,玩家从初始血量为100开始,通过加血或减血的方式穿越各个关卡。文章详细介绍了如何使用SPFA算法求解最远距离,特别关注于避免正环导致的游戏失败情况。通过深度优先搜索判断能否成功到达目标点N,为玩家提供了一个有效的生存策略。

                   题意:

                           打游戏..从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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值