hdoj 1317 XYZZY

XYZZY

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7572    Accepted Submission(s): 2162


 

Problem 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

 

Source

University of Waterloo Local Contest 2003.09.27

题目大意:有从1到n个房间,每个房间都有一个能量值,
并且有连接的房间(需要处理),每进入一次这个房间,剩余
能量值就会加上这个房间的能量,初始有100点能量,问能不能
走到最后
	解题思路:这可以抽象成一个有向图,边的权值可以理解为
弧尾的能量值,则显然这是一个含有负权值的图,这道题问是否
能成功,只要是有一条路可走就成功,所以需要求最长路,先用
Floyd算法扫描一遍连通性,然后再用Bellman-Ford算法求最长路 

#include<stdio.h>
#include<string.h>
#define maxn 0x3f3f3f3f
struct Node{
	int Start;//有向边的起始点 
	int End;//有向边的终点
}Edge,edge[10005];
int reach[110][110];
int energy[110];//每个房间的能量值 
int dist[110];//dist函数表示初始点到i的最短距离(相当于Dijkstra函数中的D数组) 
int N,edgenum;
void Floyd(){//用Floyd判断图的连通性 
	for(int k=1;k<=N;k++){ 
		for(int i=1;i<=N;i++){
			if(reach[i][k]){
				for(int j=1;j<=N;j++){
					reach[i][j]=reach[i][j]||(reach[i][k]&&reach[k][j]); 
				}
			}
		}
	}
}
int bellman_ford(){
	for(int i=1;i<=N;i++){
		dist[i]=-maxn;//如果是找最短路,初始化成最大值 
	}
	dist[1]=100;
	for(int k=0;k<N-1;k++){
		for(int i=1;i<=edgenum;i++){//对每一条边进行N-1次(N为顶点)松弛操作 
			if(dist[edge[i].End]<dist[edge[i].Start]+energy[edge[i].End]&&dist[edge[i].Start]+energy[edge[i].End]>0) {
                dist[edge[i].End]=dist[edge[i].Start]+energy[edge[i].End];
            }
		} 
	}
	if(dist[N]>0){//当到达N房间的能量为正值时赢得游戏 
		return 1;
	}
	for(int i=1;i<=edgenum;i++){//存在正环且正环上存在房间end能到达房间N 
		if(dist[edge[i].End]<dist[edge[i].Start]+energy[edge[i].End]&&dist[edge[i].Start]+energy[edge[i].End]>0){
			if(reach[edge[i].End][N]==1)
			return 1;
		}
	}
	return 0;
}
int main(){
	int conn;
	while(scanf("%d",&N)!=EOF&&N!=-1){
		memset(reach,0,sizeof(reach));
		edgenum=1;
		for(int i=1;i<=N;i++){
			int m;
			scanf("%d %d",&energy[i],&m);
			for(int j=0;j<m;j++){
				scanf("%d",&conn);
				reach[i][conn]=1;
				edge[edgenum].Start=i;
				edge[edgenum].End=conn;
				edgenum++;
			}
		}
		Floyd();
		edgenum--;//因为该算法是对边操作的,所以对边要求比较严格 
		if(bellman_ford()){
			printf("winnable\n");
		}
		else{
			printf("hopeless\n");
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Dear_Jia/article/details/81870604