HDU1317 XYZZY(Floyd+SPFA)

HDU1317 XYZZY(Floyd+SPFA)

Description
It has recently been discovered how to run open-source software on the Y-Crate gaming device. A number of enterprising designers have developed Advent-style games for deployment on the Y-Crate. Your job is to test a number of these designs to see which are winnable.
Each game consists of a set of up to 100 rooms. One of the rooms is the start and one of the rooms is the finish. Each room has an energy value between -100 and +100. One-way doorways interconnect pairs of rooms.
The player begins in the start room with 100 energy points. She may pass through any doorway that connects the room she is in to another room, thus entering the other room. The energy value of this room is added to the player’s energy. This process continues until she wins by entering the finish room or dies by running out of energy (or quits in frustration). During her adventure the player may enter the same room several times, receiving its energy each time.
Input
The input consists of several test cases. Each test case begins with n, the number of rooms. The rooms are numbered from 1 (the start room) to n (the finish room). Input for the n rooms follows. The input for each room consists of one or more lines containing:
the energy value for room i
the number of doorways leaving room i
a list of the rooms that are reachable by the doorways leaving room i
The start and finish rooms will always have enery level 0. A line containing -1 follows the last test case.
Output
In one line for each case, output “winnable” if it is possible for the player to win, otherwise output “hopeless”.
Sample Input
5
0 1 2
-60 1 3
-60 1 4
20 1 5
0 0
5
0 1 2
20 1 3
-60 1 4
-60 1 5
0 0
5
0 1 2
21 1 3
-60 1 4
-60 1 5
0 0
5
0 1 2
20 2 1 3
-60 1 4
-60 1 5
0 0
-1
Sample Output
hopeless
hopeless
winnable
winnable

题意

给定n扇门,每个门会有一定数量的路径来连接其他门,并且没经过这些路径就要改变一些权值,初始的权值为100,若从1号门走到n号门时权值还大于0,则输出winnable,否则输出hopeless。若产生了正环,则一定能走出去,但同时我们也要判断这个正环是否能走到终点,所以我们需要先使用floyd判断点与点之间的连通性,求出邻接矩阵,再用SPFA进行判断。

#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue>
#include<stack>
#include<vector>
#include<algorithm>
#include<functional> 
#include<map>
//#include<unordered_map>
#define lowbit(x) ((x)&-(x));
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e5+10,NN=1e4+10,INF=0x3f3f3f3f,LEN=110;
const ll MOD=1e9+7;
const ull seed=31;
struct Edge{
	int next,to,dis;
}edge[N];
struct Node{
	int id,dis;
	Node(int id,int dis):id(id),dis(dis){}
	bool friend operator<(const Node &a,const Node &b){
		return a.dis<b.dis;
	}
};
int num_edge,n;
int head[N];
int gra[NN][NN];
void add_edge(int from,int to,int dis){
	edge[++num_edge].next=head[from];
	edge[num_edge].to=to;
	edge[num_edge].dis=dis;
	head[from]=num_edge;
}
void floyd(){
	for(int k=1;k<=n;k++){
		for(int i=1;i<=n;i++){
			if(gra[i][k]==INF) continue;
			for(int j=1;j<=n;j++) gra[i][j]=min(gra[i][j],gra[i][k]+gra[k][j]);
		}
	}
}
int SPFA(int s){
	int dis[NN],neg[NN];
	bool inq[NN];
	memset(neg,0,sizeof neg);
	neg[s]=1;
	for(int i=1;i<=n;i++){
		dis[i]=-INF;
		inq[i]=false;
	}
	dis[s]=100;
	priority_queue<Node>q;
	q.push(Node(s,0));
	while(!q.empty()){
		Node u=q.top();
		q.pop();
		inq[u.id]=false;
		for(int i=head[u.id];i!=-1;i=edge[i].next){
			int v=edge[i].to,w=edge[i].dis;
			if(dis[u.id]+w>dis[v]&&dis[u.id]+w>0){
				dis[v]=dis[u.id]+w;
				if(!inq[v]){
					inq[v]=true;
					++neg[v];
					if(neg[v]<=n) q.push(Node(v,dis[v]));//只有当经过点的次数小于n的时候才能入队列,不然容易产生死循环
					if(neg[v]>n&&gra[v][n]!=INF) return 1;
				}
			}
		}
	}
	if(dis[n]>0) return 1;
	else return 0;
}
void init(){
	num_edge=0;
	memset(head,-1,sizeof head);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j) gra[i][j]=1;
			else gra[i][j]=INF;
		}
	}
}
int main(){
	while(scanf("%d",&n)&&(n!=-1)){
		init();
		for(int i=1;i<=n;i++){
			int w,num;
			scanf("%d%d",&w,&num);
			for(int j=1;j<=num;j++){
				int v;
				scanf("%d",&v);
				add_edge(i,v,w);
				gra[i][v]=1;
			}
		}
		floyd();
		if(SPFA(1)) printf("winnable\n");
		else printf("hopeless\n");
	}
}

猜你喜欢

转载自blog.csdn.net/Hc_Soap/article/details/107721514
今日推荐