您的位置:首页 > 其它

算法训练 最短路 Bellman-Ford

2017-02-21 16:07 393 查看
问题描述

给定一个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
,dis
;
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
;
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: