链接:



XYZZY

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

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
 
Recommend
Eddy
 

题意:


    有 N 个房间, 编号从 1 到 N 。
    每次进入一个房间, 能量值可能增加也可能减少
    问:从第一个房间开始走, 给你 100 个能量值。
        问你是否能走到第 N 个房间。

第一行 N  输入房间的个数
    然后下面 N 行数据:
        第 i  行数据的第一个表示进入该房间得到的能量【可正可负】
        第二个表示从该房间出发能到达的房间个数 num
        剩下 num 个数表示可以到达的房间编号

算法:Bellman_ford() 判断正环


注意:有向图,
      然后建图的时候要注意下, 边是没有权的。。。
      点有权

思路:


其实开始没看题目的时候,没有看到群里的吐槽也不会想到用 Bellman_ford()
      如果图中存在正环, 那么就可以不停的走这个环来增加能量,
      如果环中的点能到达 N 那么肯定是赢了。。。
      但是由于这个先入为主的思想,开始很容易的就让我忽略了,这题的本质是到达 N 的时候还有能量。
      然后就是各种不注意,各种 WA 的血泪史。。。。然后网上各种高深的题解。

      直到看到了一篇用 Bellman_ford 写的

加边建图的过程同时记录连通性, 先判断 1 与 N 在不考虑能量的时候是否连通【不判断也可以,只是个无关紧要的优化】

      然后就是套用 Bellman_ford() 判断是否有正环

注意:当不存在正环的时候, 不要像以前用这个算法时直接跳出
            因为我们的主要目的不是判断正环,而是要使得到达 N 还有能量。

那么赢的可能性就两种了:
      1.没有正环, 但是通过Bellman_ford() 的松弛操作, 到 N 的能量值 > 0
      2.存在正环, 正环中的点, 能到达终点。


code:

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std; const int maxn = 110;
const int INF = 10000000000; int w[maxn][maxn]; // 判断图的连通性
int en[maxn]; //进入该点的能量值
int d[maxn]; //每一点的能量值
int n,m; //n 个点, m 条边 struct Edge{
int u,v;
}edge[maxn*maxn]; void floyd() // 有向图的传递闭包
{
for(int k = 1; k <= n; k++)
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
w[i][j] = w[i][j] || (w[i][k] && w[k][j]); //不要写错了 WA 的都是泪。。。
} bool Bellman_ford()
{
for(int i = 1; i <= n; i++) d[i] = -INF;
d[1] = 100; // 初始第一个点有 100 个能量 for(int i = 1; i < n; i++)
{
for(int j = 0; j < m; j++)
{
int u = edge[j].u;
int v = edge[j].v; if(d[v] < d[u]+en[v] && d[u]+en[v] > 0) //松弛
d[v] = d[u]+en[v]; //是加上点的权。。。
} //注意:不能像以前一样不能松弛了,就直接返回 false 因为判断正环的目的是使 d[n] > 0
} for(int i = 0; i < m; i++)
{
int u = edge[i].u;
int v = edge[i].v; if(d[v] < d[u]+en[v] && d[u]+en[v] > 0) //如果存在正环
if(w[v][n]) //正环中的点能够到达终点
return true;
} return d[n]>0; // 不存在正环, 判断能否依靠 100 个能量值到达终点
} int main()
{
while(scanf("%d", &n) != EOF)
{
if(n == -1) break; m = 0; // 初始化边
memset(w, 0, sizeof(w));
memset(en, 0, sizeof(en));
for(int i = 1; i <= n; i++) w[i][i] = 1; int num;
for(int i = 1; i <= n; i++)
{
int v;
scanf("%d%d", &en[i], &num);
while(num--) //注意是单向的
{
scanf("%d", &v);
edge[m].u = i;
edge[m++].v = v;
w[i][v] = 1; // 有向图, 不要傻逼的加上 w[v][i] = 1
}
} floyd(); // 考查有向图的连通性
/*
if(!w[1][n])
{
printf("hopeless\n"); continue;
}*/ if(Bellman_ford()) printf("winnable\n");
else printf("hopeless\n");
}
return 0;
}


hdu 1317 XYZZY【Bellheman_ford 判断正环小应用】的更多相关文章

  1. HDU 1317 XYZZY(floyd+bellman_ford判环)

    http://acm.hdu.edu.cn/showproblem.php?pid=1317 题意: 给出一个有向图,每到达一个点,都会加上或减去一些能量,我们要做的就是判断从1出发是否能到达n.初始 ...

  2. [HDU 1317]XYZZY[SPFA变形][最长路]

    题意: 一个图, 点权代表走到该点可获得的能量值. 可正可负. 一个人从1 号出发,带有100点能量. 问是否有一种方案可使人在能量值>0的时候走到n. 思路: 这个题首先要注意点权. 其实就是 ...

  3. Currency Exchange POJ - 1860 (spfa判断正环)

    Several currency exchange points are working in our city. Let us suppose that each point specializes ...

  4. poj1860 兑换货币(bellman ford判断正环)

    传送门:点击打开链接 题目大意:一个城市有n种货币,m个货币交换点,你有v的钱,每个交换点只能交换两种货币,(A换B或者B换A),每一次交换都有独特的汇率和手续费,问你存不存在一种换法使原来的钱更多. ...

  5. Currency Exchange POJ - 1860 spfa判断正环

    //spfa 判断正环 #include<iostream> #include<queue> #include<cstring> using namespace s ...

  6. HDU 1317 XYZZY【Bellman_Ford判断正环】

    题意:给出n个房间,初始在房间1有100的能量值,每次进入一个房间,能量值可能增加也可能减小,(是点权,不是边权),问能否到达终点的时候能量值还为正 这题自己写的时候wa--wa-- 后来看了题解,还 ...

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

    XYZZY Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  8. HDU 1317XYZZY spfa+判断正环+链式前向星(感觉不对,但能A)

    XYZZY Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  9. poj 1932 XYZZY(spfa最长路+判断正环+floyd求传递闭包)

    XYZZY Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 4154   Accepted: 1185 Description ...

随机推荐

  1. CodeFirst数据库迁移小记

    打开“程序包管理器控制台”菜单项一.Enable-Migrations -ContextTypeName Code_First_数据迁移.Models.T_DbContext成功后提示:已在项目“Co ...

  2. leetcode第七题Reverse Integer (java)

    Reverse Integer Reverse digits of an integer. Example1: x = 123, return 321 Example2: x = -123, retu ...

  3. 50个实用的jQuery代码段让你成为更好的Web前端工程师

    本文会给你们展示50个jquery代码片段,这些代码能够给你的javascript项目提供帮助.其中的一些代码段是从jQuery1.4.2才开始支持的做法,另一些则是真正有用的函数或方法,他们能够帮助 ...

  4. [CC150] Find a line passing the most number of points

    Problem: Given a two-dimensional graph with points on it, find a line which passes the most number o ...

  5. Docker日志自动化: ElasticSearch、Logstash、Kibana以及Logspout

    http://www.open-open.com/lib/view/open1432107136989.html

  6. WEB SSH之Shellinabox

    用起来方便的,参考URL: http://lzw.me/a/shellinabox.html 生成 pem 证书,可以 https 方式启动.pem 证书的格式为公钥加私钥,并以 x509 的格式进行 ...

  7. 【网络流24题】No. 17 运输问题 (费用流)

    [题意] W 公司有 m 个仓库和 n 个零售商店.第 i 个仓库有ai 个单位的货物:第 j 个零售商店需要b j 个单位的货物. 货物供需平衡,即SIGMA(A)=SIGMA(B). 从第 i 个 ...

  8. USB究竟是什么?看完这篇文章我就明白了!

    在早期,USB接口的出现似乎仅仅是要解决一些简单外设诸如鼠标.键盘之类的设备与电脑的连接问题,很显然,这些外设所产生的数据量是极低的,所以,USB规范所定义的数据速率是1.5Mbps,数据还是双向分时 ...

  9. 在android4.0中实现View的拖动效果

    实现方法: 首先需要定义一个支持拖动的源组件和一个作为Drop区域的目标组件. 在支持拖动的组件中注册OnTouchListener 或LongClickListener监听事件,构建一个ClipDa ...

  10. PLSQL Developer Debug

    如果要查看存储过程或者函数的执行过程,可以用debug的模式.PLSQL Developer提供了debug功能,以函数为例: 1. 找到你要debug的函数,然后右击—>选择“Add debu ...