输入格式
第 1 行一个整数 n (1=<n≤100)。
第 2—n+1 行,每行第一个整数表示该地图体力值变化。接下来是从该房间能到达的房间名单,第一个整数表示房间数,后面是能到达的房间编号。
输出格式
若玩家能到达终点,输出Yes
,否则输出No
。
样例输入
5 0 1 2 -60 1 3 -60 1 4 20 1 5 0 0
样例输出
No
解题说明:SPFA搞搞就是了,只不过这里不断更新最大路径。然后如果dis[i]<=0了,那么我们不要把它i加入队列中,最后就是
判断环了,如果某节点加入队列中大于n,说明它能无限加深路径长度,直接记它的路径为无穷,以后不要加入队列中即可。
ac 代码:
#include<iostream> #include<algorithm> #include<string.h> #include<vector> #include<queue> using namespace std; const int MAXN=105; const int inf=0x3f3f3f3f; typedef pair<int,int>p; vector<p>ve[MAXN]; int n,cnt[MAXN],dis[MAXN]; bool mark[MAXN],markh[MAXN]; void spfa(int x){ mark[x]=true;dis[x]=100; queue<int>Q; Q.push(x);cnt[x]=1; while(!Q.empty()){ int now=Q.front();Q.pop(); for(int i=0;i<ve[now].size();i++){ int v=ve[now][i].first;int w=ve[now][i].second; if(dis[v]<dis[now]+w&&dis[now]+w>0){ dis[v]=dis[now]+w; if(!mark[v]){ if(n==++cnt[v]){ dis[v]=inf; markh[v]=true; } if(!markh[v])Q.push(v); mark[v]=true; } } } } } int main(){ cin>>n; memset(dis,1-inf,sizeof(dis)); for(int i=1;i<=n;i++){ int v,num;cin>>v>>num; for(int j=1;j<=num;j++){ int ip1;cin>>ip1; ve[i].push_back(make_pair(ip1,v)); ve[ip1].push_back(make_pair(i,v)); } } spfa(1); if(dis[n]>=0)cout<<"Yes"<<endl; else cout<<"No"<<endl; return 0; }