POJ2387求负权值

这道题是一个农场有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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值