计蒜客 闯关游戏

问题描述

蒜头君在玩一个很好玩的游戏,这个游戏一共有至多 100 个地图,其中地图 1 是起点,房间 n 是终点。有的地图是补给站,可以加 ki点体力,而有的地图里存在怪物,需要消耗 ki 点体力,地图与地图之间存在一些单向通道链接。 蒜头君从 1 号地图出发,有 100 点初始体力。每进入一个地图的时候,需要扣除或者增加相应的体力值。这个过程持续到走到终点,或者体力值归零就会 Game Over。不过,他可以经过同个地图任意次,且每次都需要接受该地图的体力值。

输入格式

第 1 行一个整数 n (n≤100)。 第 2 ~ n+1 行,每行第一个整数表示该地图体力值变化。接下来是从该房间能到达的房间名单,第一个整数表示房间数,后面是能到达的房间编号。

输出格式

若玩家能到达终点,输出Yes,否则输出No。

样例输入

5

0 1 2

-60 1 3

-60 1 4

20 1 5

0 0

样例输出

No
 

#include<bits/stdc++.h>
using namespace std;
const int MAX_N=110;
const int MAX_M=1e6;
struct edge{
	int v,next,w;
}e[2*MAX_M];
int p[MAX_N],eid;
int dst[MAX_N];
bool inq[MAX_N];
int cnt[MAX_N];
int n; 
void init(){
	memset(p,-1,sizeof(p));
	eid=0;
}
int flag=0;
void insert(int w,int u,int v){
	e[eid].v=v;
	e[eid].w=w;
	e[eid].next=p[u];
	p[u]=eid++;
}
void spfa(int s){
	for(int i=1;i<=n;i++){
		dst[i]=-0x3f3f3f3f;
	}
	memset(cnt,0,sizeof(cnt));
	dst[s]=100;
	queue<int>q;
	q.push(s);
	inq[s]=1;
	while(!q.empty()){
		int u=q.front();
		q.pop();
		inq[u]=0;
		for(int i=p[u];i+1;i=e[i].next){
			int x=e[i].v;
			if(dst[x]<dst[u]+e[i].w&&dst[u]+e[i].w>=0){
				dst[x]=dst[u]+e[i].w;
				if(!inq[x]){
					q.push(x);
					cnt[x]++;
					inq[x]=1;
				}
			}
			if(cnt[x]>n){
				flag=1;
				return;
			}
		}
	}

}
int main(){
	scanf("%d",&n);
	init();
	int w,nn,v;
	for(int i=1;i<=n;i++){
		scanf("%d%d",&w,&nn);
		for(int j=1;j<=nn;j++){
			int xx;
			scanf("%d",&xx);
			insert(w,i,xx);
		}	
	}
	spfa(1);
	if(dst[n]>0||flag){
		cout<<"Yes"<<endl;
	}else{
		cout<<"No"<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/amf12345/article/details/89035471