首页 > 其他 > 详细

POJ2387求负权值

时间:2015-03-26 01:25:29      阅读:166      评论:0      收藏:0      [点我收藏+]

这道题是一个农场有F个神奇的农场
农场有N个点,M条路,W个虫洞。虫洞能回溯时间。
问能不能从某个点出发,通过路和虫洞,回到原点,时间比原来早。

我第一思路是用bellman-ford算法,可以求是否出现负权值情况来做。
提交了好几次不对,发现坑爹之处是M条路是双向的,W个虫洞是单向的,理解了这个以后就能做了。它是要求某个点,所以要便利所有点来做bellman算法。

#include <cstring>
#include <cstdio>
#define INF 0x3f3f3f3f
using namespace std;
struct edge
{
    int from,to,cost;
    edge(int f,int t,int c):from(f),to(t),cost(c){};
    edge(){}
};
edge es[3000];
int d[550];
int F,N,M,W;
void bellman(){
    for (int k = 1; k <= N; ++k)
    {
        memset(d,INF,sizeof(d));
        d[k]=0;
        int flag=1;
        while(flag){
            flag=0;
            for (int i = 0; i < M+W; ++i)
            {
                edge e=es[i];
                if (d[e.from]!=INF&&d[e.from]+e.cost<d[e.to]&&d[e.to]>=0)
                {
                    d[e.to]=d[e.from]+e.cost;
                    flag=1;
                }               
                if (i<M&&d[e.to]!=INF&&d[e.to]+e.cost<d[e.from]&&d[e.from]>=0)
                {
                    d[e.from]=d[e.to]+e.cost;
                    flag=1;
                }
            }
        }
        if (d[k]<0){
                printf("YES\n");
                return ;
        }
    }
    printf("NO\n");
}
int main(int argc, char const *argv[])
{
    scanf("%d",&F);
    int x,y,w;
    while(F--){
        scanf("%d%d%d",&N,&M,&W);
        int i;
        for ( i = 0; i < M; ++i)
        {
            scanf("%d%d%d",&x,&y,&w);
            es[i].from=x;
            es[i].to=y;
            es[i].cost=w;
        }
        for (; i <M+W; ++i)
        {
            scanf("%d%d%d",&x,&y,&w);
            es[i].from=x;
            es[i].to=y;
            es[i].cost=-w;
        }
        bellman();
    }
    return 0;
}

POJ2387求负权值

原文:http://blog.csdn.net/ysgcreate/article/details/44631059

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!