关于有向负权图 p1807

有两种方案:①bellman_ford  ②bellman_ford的优化算法spfa

直接放代码

#include <iostream>

using namespace std;

struct edge
{
	int x, y, w;
}es[50010];

int distence[1510];


//bellman_ford这个算法其实有点类似于Floyd算法,设定起点单源
//,然后通过边的遍历来获得一个中转点,经过n轮的全边遍历,
//最长能够形成n+1个节点的最长边(在无环的情况下当然是不可能的)

int main() {

	int n, m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		cin >> es[i].x >> es[i].y >> es[i].w;
	}

	distence[1] = 0;
	for (int i = 2; i <= n; i++)
	{
		distence[i] = -1000000000;
	}


	bool flag;//用于判断该次流程是否有进行更新,若无更新,即已得到该图的最短路径
	for (int i = 0; i < n; i++)
	{
		flag = false;
		for (int j = 0; j < m; j++)
		{
			int x = es[j].x;
			int y = es[j].y;
			int w = es[j].w;
			if (distence[x] != -1000000000) {
				distence[y] = distence[x] + w > distence[y] ? distence[x] + w : distence[y];
				flag = true;
			}
			
			
		}
		if (!flag) {
			break;
		}
	}
	if (distence[n] != -1000000000) {
		cout << distence[n] << endl;
	}
	else {
		cout << -1 << endl;
	}
	

	return 0;
}

#include <iostream>
#include <queue>
#include <vector>

using namespace std;

struct edge
{
	int x, y, w;
}es[50010];

vector<int> map[1510];
queue<int> q;
bool visted[1510] = { 0 };
int dis[1510] ;


//bellman_ford的缺点在于对节点的无脑扫描,会有很多重复的操作,而spfa则是
//,每次更新操作之后,才会以更新的点为起点,在进行扫描,看看是否能够进行伸缩

int main() {
	int n,m;
	cin >> n >> m;
	for (int i = 0; i < m; i++)
	{
		cin >> es[i].x >> es[i].y >> es[i].w;
		map[es[i].x].push_back(i);
	}

	dis[1] = 0;
	for (int i = 2; i < 1510; i++)
	{
		dis[i] = -1000000;
	}
	
	q.push(1);
	visted[1] = 1;
	while (!q.empty())
	{
		int x = q.front();
		q.pop();
		visted[x] = 0;

		int en = 0;
		int to = 0;
		int w = 0;
		for (int i = 0; i < map[x].size(); i++)
		{
			en = map[x][i];
			to = es[en].y;
			w = es[en].w;
			if (dis[to] < dis[x] + w) {
				dis[to] = dis[x] + w;
				if (!visted[to]) {
					q.push(to);
				}
			}
		}
	}
	if (dis[n] == -1000000) {
		cout << -1 << endl;
	}
	else {
		cout << dis[n];
	}
	






	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值