HDU 1317(Floyd判断连通性+spfa判断正环)

XYZZY

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

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

题意:从第一个房间开始有100的初始能量。每经过一个房间加上此房间的能量值,如果能量为负或者到达终点则停止。问能不能到达终点。

题解:首先先用Floyd判断连通性,如果不连通则结束。如果联通用spfa判断有没有正环,即cnt[v]>=n则有正环,有正环判断环上一点到终点是否联通。没有环的话,则判断到达终点最长的通路能量值是否大于0即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <vector>
 5 #include <cstring>
 6 #include <queue>
 7 using namespace std;
 8 const int maxn = 105;
 9 const int INF = 0x3f3f3f3f;
10 int n;
11 int energy[maxn];
12 int power[maxn];   //记录到每一点的力量值
13 int cnt[maxn];   //记录访问每一个点的次数
14 bool g[maxn][maxn];
15 bool reach[maxn][maxn];
16 void floyd()
17 {
18     for(int k = 1; k<=n; k++)
19         for(int i = 1; i<=n; i++)
20             for(int j = 1; j<=n; j++)
21             if(reach[i][j]||(reach[i][k]&&reach[k][j])) reach[i][j] = true;
22 }
23 bool spfa(int s)
24 {
25     queue<int> q;
26     memset(power,0,sizeof(power));
27     power[s] = 100;
28     memset(cnt,0,sizeof(power));
29     q.push(s);
30     while(!q.empty())
31     {
32         int v = q.front();
33         q.pop();
34         cnt[v]++;
35         if(cnt[v]>=n) return reach[v][n]; //有正环
36         for(int i = 1; i<=n; i++)
37         {
38             if(g[v][i]&&power[i]<power[v]+energy[i]&&power[v]+energy[i]>0)
39             {
40                 power[i] = power[v]+energy[i];
41
42                 q.push(i);
43             }
44         }
45     }
46     return power[n]>0;
47
48 }
49 void solve()
50 {
51     while(scanf("%d",&n)!=EOF&&n!=-1)
52     {
53         memset(g,false,sizeof(g));
54         memset(reach,false,sizeof(reach));
55         for(int i = 1; i<=n; i++)
56         {
57             int k,door;
58             scanf("%d %d",&energy[i],&k);
59             for(int j = 1; j<=k; j++)
60             {
61                 scanf("%d",&door);
62                 g[i][door] = true;
63                 reach[i][door] = true;
64             }
65         }
66         floyd();
67         if(!reach[1][n])
68         {
69             printf("hopeless\n");
70             continue;
71         }
72         if(spfa(1))
73         {
74             printf("winnable\n");
75         }
76         else
77         {
78             printf("hopeless\n");
79         }
80     }
81 }
82 int main()
83 {
84     solve();
85     return 0;
86 }
时间: 2024-10-15 06:51:09

HDU 1317(Floyd判断连通性+spfa判断正环)的相关文章

POJ 1860 货币兑换 SPFA判正环

Currency Exchange Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 20280   Accepted: 7270 Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and pe

POJ 1860——Currency Exchange——————【最短路、SPFA判正环】

Currency Exchange Time Limit:1000MS     Memory Limit:30000KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 1860 Description Several currency exchange points are working in our city. Let us suppose that each point specializes in two par

POJ 3621 Sightseeing Cows 【01分数规划+spfa判正环】

题目链接:http://poj.org/problem?id=3621 Sightseeing Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11526   Accepted: 3930 Description Farmer John has decided to reward his cows for their hard work by taking them on a tour of the big ci

poj1860(spfa判正环)

题目连接:http://poj.org/problem?id=1860 题意:有多种从a到b的汇率,在你汇钱的过程中还需要支付手续费,那么你所得的钱是 money=(nowmoney-手续费)*rate,现在问你有v钱,从s开始出发交换钱能不能赚钱. 分析:如何存在正环,能无限增加钱,肯定可以赚了,因此用spfa判一下即可 #include <cstdio> #include <cstring> #include <string> #include <cmath&

POJ1680 Currency Exchange SPFA判正环

转载来源:優YoU  http://user.qzone.qq.com/289065406/blog/1299337940 提示:关键在于反向利用Bellman-Ford算法 题目大意 有多种汇币,汇币之间可以交换,这需要手续费,当你用100A币交换B币时,A到B的汇率是29.75,手续费是0.39,那么你可以得到(100 - 0.39) * 29.75 = 2963.3975 B币.问s币的金额经过交换最终得到的s币金额数能否增加 货币的交换是可以重复多次的,所以我们需要找出是否存在正权回路,

hdu1317(spfa判断正环+Floyd判断联通)

题意很好理解,判断是否能从起点走到终点,每走到几个点就会获得这个点所代表的能量值,起点时自身带有100能量值. 刚开始写了个裸地spfa,超时了,发现可能存在从起点走不到终点,而且还存在正环,这样程序永远也不会结束,改正后用Floyd判断起点和终点是否联通,然后用spfa求最长路,遇到环中的点时判断,环中的点是否能到达终点,能到达则输出“winnable”,因为可以在正环中获得无限能量值. 不能的话继续做spfa, 并且环中的点不再进入队列,这个换就被破坏了,这样就算图中有多个环也能处理.若没有

POJ 1860 (SPFA判断正环)

题意:我们的城市有几个货币兑换点.让我们假设每一个点都只能兑换专门的两种货币.可以有几个点,专门从事相同货币兑换.每个点都有自己的汇率,外汇汇率的A到B是B的数量你1A.同时各交换点有一些佣金,你要为你的交换操作的总和.在来源货币中总是收取佣金. 例如,如果你想换100美元到俄罗斯卢布兑换点,那里的汇率是29.75,而佣金是0.39,你会得到(100 - 0.39)×29.75=2963.3975卢布. 你肯定知道在我们的城市里你可以处理不同的货币.让每一种货币都用唯一的一个小于N的整数表示.然

POJ 1860 Currency Exchange(如何Bellman-Ford算法判断正环)

题目链接: https://cn.vjudge.net/problem/POJ-1860 Several currency exchange points are working in our city. Let us suppose that each point specializes in two particular currencies and performs exchange operations only with these currencies. There can be s

luogu3778/bzoj4898 商旅 (floyd+分数规划+spfa)

首先floyd求出来每两点间的最短距离,然后再求出来从某点买再到某点卖的最大收益 问题就变成了找到一个和的比值最大的环 所以做分数规划,二分出来那个答案r,把边权变成w[i]-r*l[i],再做spfa判正环就行了 (本来想偷懒用floyd判正环,结果T了) 1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace s