问题描述
给定一个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;
}