POJ-3259 Wormholes (Bellman-Ford判负环问题)

题目链接

题意:给出n个点,m条正权无向边,s条负权有向边,问是否存在负环.

题解:Bellman-Ford判负环问题,套一波模板.

代码如下:

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 1005
struct edge
{
	int u, v, dis;
};
vector<edge>e;
int dis[1005];
void Bellman_Ford(int n)
{
	for (int i = 1; i <= n; i++)
		dis[i] = inf;
	dis[1] = 0;
	for (int k = 1; k < n; k++) //先进行n-1次取点
		for (int i = 0; i < e.size(); i++)
		{
			edge &p = e[i];
			if (dis[p.u] != inf&&dis[p.u] + p.dis < dis[p.v]) //松弛
				dis[p.v] = dis[p.u] + p.dis;
		}
}
bool check(int n)
{
	for (int i = 0; i < e.size(); i++)
	{
		edge &p = e[i];
		if (dis[p.u] != inf&&dis[p.u] + p.dis < dis[p.v])   //判断是否还能进行松弛,若能说明存在负环
			return true;
	}
	return false;
}
void solve(int n)
{
	Bellman_Ford(n);
	if (check(n))printf("YES\n");
	else printf("NO\n");
}

int main()
{
	int t;
	scanf("%d", &t);
	while (t--)
	{
		int n, m, s;
		scanf("%d%d%d", &n, &m, &s);
		e.clear();
		while (m--)//m条正权无向边
		{
			edge p1, p2;
			scanf("%d%d%d", &p1.u, &p1.v, &p1.dis);
			p2.u = p1.v;
			p2.v = p1.u;
			p2.dis = p1.dis;
			e.push_back(p1);
			e.push_back(p2);
		}
		while (s--)//s条负权有向边
		{
			edge p;
			scanf("%d%d%d", &p.u, &p.v, &p.dis);
			p.dis = -p.dis;
			e.push_back(p);
		}
		solve(n);
	}
}




 

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