Wormholes POJ - 3259 最短路之找负圈(Bellman-Ford)

传送门

题目大意: 约翰有N个农场, 农场之间有M条路 和 W 个虫洞, 其中路是双向的, 话费时间t, 而虫洞花费的时间是负的, 而且是单向的. 问, 约翰能不能从一个农场出发, 通过这些虫洞和路回到这个农场, 而且时间在这个时间之前.

题目分析: 很明显是找负圈的裸题, 农场做顶点, 路和虫洞做边建图, 其中虫洞的边权重是负的即可. 用Bellman-Ford算法找有没有负圈即可.

代码:

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;
const int INF = 1e5;
const int MAXN = 505;
int d[MAXN];
int maxE;
struct edge
{
    int fo, to;
    int t;
}E[5550];

bool Bellman_Ford(int maxV)
{
    memset(d, 0, sizeof d);
    
    for(int i=0; i<maxV; ++i)
    {
        bool update = false;
        for(int j=0; j<maxE; ++j)
        {
            edge e = E[j];
            if(d[e.fo] + e.t < d[e.to])
            {
                update = true;
                d[e.to] = d[e.fo] + e.t;
            }
        }
        if(!update) break;
        if(i == maxV-1) return true;
    }
    return false;
}	


int main()
{
    int T, n, m, w;
    int s, e, t;
    cin >>T;
    while(T--)
    {
        scanf("%d%d%d", &n, &m, &w);
        for(int i=0; i<m; ++i)
        {
            scanf("%d%d%d", &s, &e, &t);
            E[i] = (edge){s, e, t};
            E[i+m] = (edge){e, s, t};
        }
        for(int i=0; i<w; ++i)
        {
            scanf("%d%d%d", &s, &e, &t);
            E[i+m*2] = (edge){s, e, -t};
        }
        maxE = m*2+w;
        if(Bellman_Ford(n)) printf("YES\n");
        else printf("NO\n");
    }

    return 0;
}

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