您的位置:首页 > 其它

hdu 1317 XYZZY【BellmanFord+Floyd】

2016-05-24 18:41 513 查看

XYZZY

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


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

 

题目大意:

输入n个点,接下来n行,表示n个点的信息,第一个数表示在这点必须拿的点数,接下来一个数q表示这个节点能到达的节点的个数,接下来q个数表示这个点能够到达的节点编号。

问能否走到终点,点可以走多次,点数也可以重复拿取,起始的时候有100点,如果路途中为负值,就算输了。

思路:

1、把能够拿到的点数作为边权值,建图,因为我们想要值越来越大,所以我们这里求的不是最短路,而是最长路。那么有一种情况比较特殊:正权回路,能够一直拿取点数,那么无论之后的路径权值为多小,我们都一定能够走出去。那么我们就清楚了什么时候算赢:有正权回路,或者是最长路值大于0

2、我们考虑这样一个问题,如果有正权回路了,就一定能够走到终点吗?显然不是的,首先图要保证是连通的,从1能够走到n,另外一个重要的点就是从这个环要能够走到n这个点才行,所以我们这里可以使用floyd算法求一下连通性,如果u能够走到v,那么map【u】【v】=1,然后进行一次传递闭包,如果遇到了正权回路,那么我们也就能判断能否走到终点了。

3、在求最长路的过程中,千万千万要保证更新的值要大于0.

AC代码:

#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
int dis[1212];
int map[105][105];
int val[105];
vector<int >mp[105];
int n;
int BellmanFord()
{
for(int i=1;i<=n;i++)
{
dis[i]=-0x3f3f3f3f;
}
dis[1]=100;
for(int k=1;k<=n-1;k++)
{
int check=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<mp[i].size();j++)
{
int v=mp[i][j];
if(dis[v]<dis[i]+val[i]&&dis[i]+val[i]>0)
{
dis[v]=dis[i]+val[i];
check=1;
}
}
}
if(check==0)break;
}
int flag=0;
for(int i=1;i<=n;i++)
{
for(int j=0;j<mp[i].size();j++)
{
int v=mp[i][j];
if(dis[v]<dis[i]+val[i]&&map[i]
&&dis[i]+val[i]>0)
{
flag=1;
break;
}
}
}
if(flag==1)return 1;
else return dis
>0;
}
void Floyd()
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
for(int k=1;k<=n;k++)
{
if(map[j][i]==1&&map[i][k]==1)
{
map[j][k]=1;
}
}
}
}
}
int main()
{
while(~scanf("%d",&n))
{
if(n<0)break;
memset(map,0,sizeof(map));
for(int i=1;i<=n;i++)
{
mp[i].clear();
}
for(int i=1;i<=n;i++)
{
int q;
scanf("%d%d",&val[i],&q);
while(q--)
{
int v;
scanf("%d",&v);
mp[i].push_back(v);
map[i][v]=1;
}
}
Floyd();
if(map[1]
==1)
{
if(BellmanFord())
printf("winnable\n");
else printf("hopeless\n");
}
else printf("hopeless\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  hdu 1317 杭电 1317