闯关游戏SPFA

输入格式

第 1 行一个整数 n (1=<n100)。

第 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;
} 

猜你喜欢

转载自blog.csdn.net/zxk_hi/article/details/80031915