Hdu 1317 XYZZY[floyd+bellman_ford]

题目链接:点击打开链接

简单来说,就是从房间1走到n的可能性,如果可能,winnable,否则,hopeless。每到达一个房间可以得到,一个房间内的能量。能量小于等于0的时候,就是游戏结束的时候。

一个最短路的问题,思路很清晰并且真确的时候,就很简单了。

首先,说一下自己的想法为什么错误了。

这题的关键就是在于,如果存在正环,那么正环中的节点是否可以到达1点和n点。

那么,存在正环的话,不一定就一定能到达n点。为什么?因为,可能正环中的节点不一定能到达n点。

怎么样来判断,正环中的点是否能到达n点就成了该题目的关键点。

我一开始先到的是,bellman松弛一遍,然后再次松弛一遍,如果第二遍的dis[n]>第一遍的dis[n],那么就是可以到达。事实证明,这种想法是错误的。

为什么类?因为,如果第一次松弛不能到达n点的话,第二次松弛,还有可能不能到达n点。这样就会出现错误。

后来,找到别人的思路。

floyd先判断一下连通性,然后,再判断如果存在正环的话,正环中的节点是否和n点连通吗,若连通,一定能够到达。否则,不能。

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

const int N=103;
const int M=10004;
const int INF=-0xffffff;
int dis[N],n,top,energy[N];
bool dp[N][N];
struct DoorWay{
    int start,end;
}way[M];

void floyd(){
    for(int k=1;k<=n;k++){
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
            dp[i][j]=dp[i][j]||(dp[i][k]&&dp[k][j]);
        }
    }
}

void Bellman_ford(){
    for(int i=1;i<=n;i++)
    dis[i]=INF;
    dis[1]=100;
    for(int i=1;i<n;i++){
        for(int j=1;j<=top;j++){
            int st=way[j].start;
            int en=way[j].end;
            if(dis[en]<dis[st]+energy[en]&&dis[st]+energy[en]>0)
            dis[en]=dis[st]+energy[en];
        }
    }
    bool flag=false;
    for(int i=1;i<=top;i++){
        int st=way[i].start;
        int en=way[i].end;
        if(dis[en]<dis[st]+energy[en]&&dis[st]+energy[en]>0&&dp[en][n]){
            flag=true;
            printf("winnable\n");
            break;
        }
    }
    if(!flag){
        if(dis[n]>0) printf("winnable\n");
        else printf("hopeless\n");
    }
}

int main(){
    while(scanf("%d",&n)&&(n!=-1)){
        top=0;
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++) dp[i][i]=true;
        for(int i=1;i<=n;i++){
            int number,id;
            scanf("%d%d",&energy[i],&number);
            for(int j=1;j<=number;j++){
                scanf("%d",&id);
                top++;
                dp[i][id]=true;
                way[top].start=i;
                way[top].end=id;
            }
        }
        floyd();
        Bellman_ford();
    }
    return 0;
}

还是需要正确的想法。

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/creat2012/article/details/20988705
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞