问题描述
蒜头君在玩一个很好玩的游戏,这个游戏一共有至多 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;
}