hdu1317 XYZZY Floyd + Bellman_Ford

  这题,我在学搜索的时候做过。不过好像不叫这名字。

  1、先用Floyd算法判断图的连通性。如果1与n是不连通的,输出hopeless。

  2、用Bellman_Ford算法判断是否有正圈,如果某点有正圈,并且该点与第n点是连通的。就输出winnable。当然,没有正圈的情况下,可以到达也是可以的。然后就是如何找正圈的问题。Bellman_Ford算法可以判断有没有负圈。Bellman_Ford是解决最短路问题的,核心是松弛法。如果dist[v]<dist[u]+Map[u][v],则dist[v]=dist[u]+Map[u][v]。在循环n-1次以后,如果还存在dist[v]<dist[u]+Map[u][v],则说明有负圈。这样,我们找正圈也有方法了:dist数组初始化为负无穷。如果dist[v]>dist[u]+Map[u][v],则dist[v]=dist[u]+Map[u][v]。循环n-1次以后,如果还存在dist[v]>dist[u]+Map[u][v],则说明有正圈。

  其中,要注意的是。可以往下一房间走的条件是当前的能量值大于0。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 105, M = N*N/2, INF=0x3f3f3f3f;
int dist[N],f[N][N], g[N];
struct node
{
    int x,y;
}e[M];
int n,m;
void floyd()
{
    int i,j,k;
    for(k=1;k<=n;k++)
        for(i=1;i<=n;i++)
            for(j=1;j<=n;j++)
                f[i][j]=f[i][j]||(f[k][j]&&f[i][k]);

}
bool bellman_ford(int s)
{
    int i,j,k;
    for(i=1;i<=n;i++) dist[i]= -INF;
    dist[s]=100;
    for(i=1;i<n;i++) //n-1次
    {
        for(j=0;j<m;j++)
        {
            int x=e[j].x, y=e[j].y;
            if(dist[y]<dist[x] + g[y]&&dist[x]+g[y]>0)
                dist[y]=dist[x] + g[y];
        }
    }
    for(j=0;j<m;j++)
    {
        int x=e[j].x, y=e[j].y;
        if(dist[y]<dist[x] + g[y]&&dist[x]+g[y]>0&&f[y][n]) return 1;  //有负环回路
    }
    return dist[n]>0;
}
int main()
{
    //freopen("test.txt","r",stdin);
    int i,j,k,t;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==-1) break;
        m=0;
        memset(f,0,sizeof(f));
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&g[i],&j);
            while(j--)
            {
                scanf("%d",&k);
                f[i][k]=1;
                e[m].x=i;e[m].y=k;
                m++;
            }
        }
        floyd();
        if(!f[1][n])
        {
            printf("hopeless\n");
            continue;
        }
        if(bellman_ford(1)) printf("winnable\n");
        else printf("hopeless\n");
    }
    return 0;
}

  PS:我感觉写解题报告还是很有必要的。让自己去总结,弄明白解题思路。当然,也可以给别人提供一些思路。

时间: 2024-10-09 02:51:47

hdu1317 XYZZY Floyd + Bellman_Ford的相关文章

HDU 1317 XYZZY(floyd+bellman_ford判环)

http://acm.hdu.edu.cn/showproblem.php?pid=1317 题意: 给出一个有向图,每到达一个点,都会加上或减去一些能量,我们要做的就是判断从1出发是否能到达n.初始能量有100,行走的途中能量不能小于等于0. 思路: 首先我们用floyd来判断一下1和n之间是否有通路. 其次就是bellman_ford算法来判正环了. 1 #include <iostream> 2 #include <cstring> 3 #include <algori

HDU 1317 XYZZY【Bellman_Ford判断正环】

题意:给出n个房间,初始在房间1有100的能量值,每次进入一个房间,能量值可能增加也可能减小,(是点权,不是边权),问能否到达终点的时候能量值还为正 这题自己写的时候wa--wa-- 后来看了题解,还是wa---wa--- 题解很详细http://blog.csdn.net/freezhanacmore/article/details/9937327 记录下自己犯的错误吧 首先是floyd函数初始化的时候,直接写在了函数里面,这样是不对的,因为输入值在前,调用函数在后,这样就相当于将之前输入的可

HDU - 1317 XYZZY (floyd + 最长路)

题目大意:有一种游戏,游戏里面有N个房间,每个房间有相应的能量值,走入该房间就可以得到相应的能量值 现在你要从房间1出发,走到房间N,如果中途能量耗尽了,就表示输了,反之,则为赢 解题思路:首先得判断一下能不能到达N,这可以用Floyd去判断 如果能直接走到N的话,就算赢,否则判断一下,看是否有正环,且正环中有点能到N #include <cstdio> #include <cstring> #include <algorithm> #include <vecto

POJ1932 HDU1317 ZOJ1935 UVA10557 XYZZY【SPFA+Floyd】

XYZZY Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 4217 Accepted: 1203 Description The prototypical computer adventure game, first designed by Will Crowther on the PDP-10 in the mid-1970s as an attempt at computer-refereed fantasy gamin

(HDU1317)XYZZY(Floyd+spfa)

XYZZY Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5804    Accepted Submission(s): 1681 Problem Description It has recently been discovered how to run open-source software on the Y-Crate gami

HDU 1317 XYZZY (SPFA 找正环 + Floyd 判连通)

XYZZY Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3004    Accepted Submission(s): 817 Problem Description It has recently been discovered how to run open-source software on the Y-Crate gami

最短路算法(dijkstra,bellman_ford,floyd)

最短路算法 dijkstra(初级的最短路算法,适合稠密图,可用邻接表优化) bool relax(int u,int v) { double tmp=max(dist[u],edge[u][v]); if(tmp<dist[v]){ dist[v]=tmp; } } void dijkstra() { memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++){ int x; double mindist=INF; for(int j=0;j<n;j

最短路(Floyd)-hdu1317

题目链接:https://vjudge.net/problem/HDU-1317 题目描述: 题意:玩家起始有100个能量点,刚开始在起始房间中,每个房间外有一条单向的路径通往其他房间(一个房间可能通往多个房间),具体通往哪些房间可以查看房间门口的房间列表.每次玩家进入一个房间,他的能量值会更新成 当前自身能量值+房间能量值(重点是房间的能量值可能为负值).玩家想要终止游戏的话,要么是能够进入到终点房间,要么是因能量耗尽而累死.需要我们判断玩家能否进入到终点房间. Floyd算法(Floyd-W

最短路(Dijkstra,Floyd,Bellman_Ford,SPFA)

当然,这篇文章是借鉴大佬的... 最短路算法大约来说就是有4种——Dijkstra,Floyd,Bellman_Ford,SPFA 接下来,就可以一一看一下... 1.Dijkstra(权值非负,适用于有向图及无向图,单源最短路) 1 Dijkstra's算法解决的是图中单个源点到其它顶点的最短路径.只能解决权值非负(看了代码就知道了)2 Dijkstral只能求出任意点到达源点的最短距离(不能求出任意两点之间的最短距离),同时适用于有向图和无向图,复杂度为O(n^2).3算法的过程: 1设置顶