XYZZY HDU - 1317 SPFA判正环

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点能量,每到一个房间,你就会获得或者减少一些能量,如果能量<=0,你就会死,最初你在1号房间里,问你能否活着到达n号房间。

思路:如果到达n号房间的路上存在正环,那么一定就可以到达n号房间。但并不是有正环就一定能到达。(我在这个地方wa了好多次)。

如图:

在这里插入图片描述
这种情况下,即使有正环也会死掉。

因此,我们发现一些点在正环里时,我们把这些点的权值修改为无穷(因为在正环中走无穷次后每个点能量变为inf),每当我们走到正环中的点时就跳过该点去走别的点,看是否能够走到终点

#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=1100;
const int inf=0x3f3f3f3f;
int head[maxn],book[maxn],dis[maxn],cont[maxn],val[maxn],cnt,n;
struct node{
	int id;
	int next;
}side[maxn*maxn];
void init()
{
	memset(head,-1,sizeof(head));
	memset(book,0,sizeof(book));
	memset(cont,0,sizeof(cont));
	memset(dis,0,sizeof(dis));
	cnt=0;
}
void add(int x,int y)
{
	side[cnt].id=y;
	side[cnt].next=head[x];
	head[x]=cnt++;
}
void SPFA(int sx)
{
	queue<int> q;
	dis[sx]=100;
	book[sx]=1;
	cont[sx]=1;
	q.push(sx);
	while(q.size())
	{
		int x=q.front();
		q.pop();
		book[x]=0;
		if(cont[x]>n) continue;
		for(int i=head[x];i!=-1;i=side[i].next)
		{
			int y=side[i].id;
			if(dis[y]<dis[x]+val[y])
			{
				dis[y]=dis[x]+val[y];
				if(!book[y])
				{
					book[y]=1;
					cont[y]++;
					if(cont[y]>=n) dis[y]=inf;
					q.push(y);
				}
			}
		}
	}
}
int main()
{
	int k,x;
	while(~scanf("%d",&n)&&n!=-1)
	{
		init();
		for(int i=1;i<=n;i++)
		{
			scanf("%d%d",&val[i],&k);
			while(k--)
			{
				scanf("%d",&x);
				add(i,x);
			}
		}
		SPFA(1);
		if(dis[n]>0)
			printf("winnable\n");
		else
			printf("hopeless\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/why932346109/article/details/88954703