题目大意:原题链接

给你一张图,初始你在房间1,初始生命值为100,进入每个房间会加上那个房间的生命(可能为负),问是否能到达房间n。(要求进入每个房间后生命值都大于0)

解题思路:

解法一:Floyd+Bellman

1.Floyd先判断图是否连通,不连通则直接失败

2.Bellman Ford然后跑最长路,判断是否有正环或者有正通路

#include<cstdio>
#include<cstring>
using namespace std;
int n,val[],d[];
bool graph[][],link[][];
int main()
{
int i,j,k,cnt,id;
while(scanf("%d",&n),n!=-){
memset(d,-,sizeof(d));
memset(val,,sizeof(val));
memset(link,false,sizeof(link));
memset(graph,false,sizeof(graph));
for(i=;i<=n;i++){
scanf("%d%d",&val[i],&cnt);
while(cnt--){
scanf("%d",&id);
graph[i][id]=true;
link[i][id]=true;//用于判断任意两点间的连通性
}
}
//Floyd判断连通性
for(k=;k<=n;k++){
for(i=;i<=n;i++){
for(j=;j<=n;j++){
if(link[i][k]&&link[k][j])
link[i][j]=true;
}
}
}
if(!link[][n]){
printf("hopeless\n");
continue;
}//必须加上这个
link[n][n]=true;
//Bellman-ford求最长路径
d[]=;
for(k=;k<=n;k++){//遍历每一个节点
bool sign=true;
for(i=;i<=n;i++){//遍历每一条边
for(j=;j<=n;j++){//j,n必须是连通的,并且前一个点d[i]为正
if(graph[i][j]&&link[j][n]&&d[j]<d[i]+val[j]&&d[i]>){
d[j]=d[i]+val[j];
sign=false;
}
}
}//如果d[j]已经不能更新了,说明最长路已经查找完毕,即不存在正环,退出循环
if(sign) break;
}
if(k>n||d[n]>) printf("winnable\n");//有正环或者有正通路
else printf("hopeless\n");
}
}

解法二:Spfa+Floyd

1.Spfa先判正环+跑最长路,以及判断是否存在正通路

2.若d[n]<=0,则Floyd然后根据存在正环以及是否连通起点和终点判断是否会成功到达n点

#include<cstdio>
#include<cstring>
#include<queue>
#define inf 0x3f3f3f3f
using namespace std;
int n,p,num[];//num[u]表示u入队次数
int val[],d[];
bool in[],link[][];
queue<int> que;
bool Spfa_floyd(int u)
{
for(int i=;i<=n;i++){
d[i]=-inf;
in[i]=,num[i]=;
}
while(!que.empty()) que.pop();//que定义为全局变量就得清空队列
que.push(u);
in[u]=true;
num[u]=,d[u]=;
while(!que.empty()){
u=que.front();
que.pop();
in[u]=false;
if(num[u]>n){
p=u;
break;//Spfa某节点入队次数大于n则有正环
}
for(int v=;v<=n;v++){
if(link[u][v]&&d[u]+val[v]>&&d[u]+val[v]>d[v]){
d[v]=d[u]+val[v];//最长路
if(!in[v]){
que.push(v);
in[v]=true;
num[v]++;
}
}
}
}
if(d[n]>) return true;
else{
for(int k=;k<=n;k++)
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
if(link[i][k]&&link[k][j])
link[i][j]=true;
if(num[p]>n&&link[][p]&&link[p][n])
return true;//如果存在正环,并且连接起点和终点
return false;
}
} int main()
{
while(scanf("%d",&n),n!=-){
memset(link,,sizeof(link));
memset(val,,sizeof(val));
for(int i=;i<=n;i++){
int cnt,id;
scanf("%d%d",&val[i],&cnt);
for(int j=;j<=cnt;j++){
scanf("%d",&id);
link[i][id]=true;
}
}
if(Spfa_floyd()) puts("winnable");
else puts("hopeless");
}
}

PKU 1932 XYZZY(Floyd+Bellman||Spfa+Floyd)的更多相关文章

  1. POJ 1932 XYZZY (ZOJ 1935)SPFA+floyd

    http://poj.org/problem?id=1932 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1935 题目大 ...

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

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

  3. 最短路问题(Bellman/Dijkstra/Floyd)

    最短路问题(Bellman/Dijkstra/Floyd) 寒假了,继续学习停滞了许久的算法.接着从图论开始看起,之前觉得超级难的最短路问题,经过两天的苦读,终于算是有所收获.把自己的理解记录下来,可 ...

  4. HDU 2992 Hotel booking(BFS+DFS 或者 SPFA+Floyd)

    点我看题目 题意 : 一个司机要从1点到达n点,1点到n点中有一些点有宾馆,司机的最长开车时间不能超过10小时,所以要在10小时之内找到宾馆休息,但是为了尽快的走到n点,问最少可以经过几个宾馆. 思路 ...

  5. 四大算法解决最短路径问题(Dijkstra+Bellman-ford+SPFA+Floyd)

    什么是最短路径问题? 简单来讲,就是用于计算一个节点到其他所有节点的最短路径. 单源最短路算法:已知起点,求到达其他点的最短路径. 常用算法:Dijkstra算法.Bellman-ford算法.SPF ...

  6. 最短路算法详解(Dijkstra/SPFA/Floyd)

    新的整理版本版的地址见我新博客 http://www.hrwhisper.me/?p=1952 一.Dijkstra Dijkstra单源最短路算法,即计算从起点出发到每个点的最短路.所以Dijkst ...

  7. poj 1932 XYZZY (最短路径)

    XYZZY Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3105   Accepted: 887 Description ...

  8. 一个人的旅行(floyd+dijskra+SPFA+Bellman)

    一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  9. 最短路知识点总结(Dijkstra,Floyd,SPFA,Bellman-Ford)

    Dijkstra算法: 解决的问题: 带权重的有向图上单源最短路径问题.且权重都为非负值.如果采用的实现方法合适,Dijkstra运行时间要低于Bellman-Ford算法. 思路: 如果存在一条从i ...

随机推荐

  1. 学习:java代码检测

    转自:http://zh.wikipedia.org/wiki/%E4%BB%A3%E7%A0%81%E5%BC%82%E5%91%B3 对于Java开发语言,有些工具,比如Checkstyle.PM ...

  2. 【代码备份】NLM插值

    文件路径: main.m: %% 测试函数 clc,clear all,close all; %输入的原始小图 ima_ori=double(imread('F:\Users\****n\Docume ...

  3. C++ 智能指针学习

     C++ Code  12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 ...

  4. Lumen Carbon 日期及时间处理包

    用到过的方法: 获取当前Y-m-d H:i:s Carbon::now()->toDateTimeString() 把 Y-m-d H:i:s 转 Y-m-d Carbon::parse('Y- ...

  5. ios开发之 -- UIView总结

    如果想调用某个类的某个方法可以写成这样,这个方法来自NSObject类 performSelector: performSelector:withObject: performSelector:wit ...

  6. Invalid property 'driverClassName' of bean class [com.mchange.v2.c3p0.ComboPooledDataSource]

    spring配置文件中配置c3p0错误,错误原因在于c3p0连接池与DBCP连接池在驱动.连接.数据库用户名这些属性名称的差别

  7. shell脚本学习总结03--别名的使用

    1.创建别名 $ alias dms='cd Oracle/Middleware/user_projects/domains/7001_costctl/' $ dms $ dms $ pwd /hom ...

  8. std::thread(2)

    个线程都有一个唯一的 ID 以识别不同的线程,std:thread 类有一个 get_id() 方法返回对应线程的唯一编号,你可以通过 std::this_thread 来访问当前线程实例,下面的例子 ...

  9. docker harbor 安装 使用总结

    总结:没有验证,但是猜测. 我这个harbor的机器上  有起了一个 docker的 registry, 5000端口的,不知道是不是二者冲突. 猜测是这个情况. 1. 安装参考 收藏的链接 1.1  ...

  10. [报错]编译报错:clang: error: linker command failed with exit code 1及duplicate symbol xxxx in错误解决方法之一

    今天添加了一个新类(包括m,h,xib文件),还没有调用,—编译遇到如下错误,根据错误提示, duplicate symbol param1 in: /Users/xxxx/Library/Devel ...