算法训练 最短路 Bellman-Ford

问题描述

给定一个n个顶点,m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路(顶点从1到n编号)。

输入格式

第一行两个整数n, m。

接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。

输出格式 共n-1行,第i行表示1号点到i+1号点的最短路。 样例输入 3 3

1 2 -1

2 3 -1

3 1 2 样例输出 -1

-2 数据规模与约定

对于10%的数据,n = 2,m = 2。

对于30%的数据,n <= 5,m <= 10。

对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。

思路:

因为题目中说有负权边,所以我们就不能使用dijkstra算法了,只能选用Bellman-Ford 这里用了队列优化

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int N=20010;
const int M=200010;
int book[N],dis[N];
int n,m;
struct node
{
	int to;
	int cost;
};
int main()
{
	int t;
	struct node temp;
	memset(book,0,sizeof(book));
	scanf("%d%d",&n,&m);
	vector<node>eg[N];
	queue<int>Q;
	for(int i=1;i<=m;i++)
	{
		scanf("%d %d %d",&t,&temp.to,&temp.cost);
		eg[t].push_back(temp);
	}
	for(int i=1;i<=n;i++)
	dis[i]=inf;
	dis[1]=0;
	Q.push(1);
	book[1]=1;
	while(!Q.empty())
	{
		int w=Q.front();
		Q.pop();
		for(int i=0;i<eg[w].size();i++)
		{
			if(dis[eg[w][i].to]>dis[w]+eg[w][i].cost)
			{
			 dis[eg[w][i].to]=dis[w]+eg[w][i].cost;
				if(book[eg[w][i].to]==0)
				{
					book[eg[w][i].to]=1;
					Q.push(eg[w][i].to);
				}
			}
		}
		book[w]=0;
	}
	for(int i=2;i<=n;i++)
	{
		printf("%d\n",dis[i]);
	}
	return 0;
}

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