链接:https://ac.nowcoder.com/acm/problem/14369
来源:牛客网
题目描述
简单暴力的题目要求:
给定一个有n个顶点(从1到n编号),m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路。
输入描述:
第一行两个整数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
解题思路
这道题用的方法是spfa+前向星图,存图然后遍历,再输出
解题代码
#include<bits/stdc++.h>
using namespace std;
int head[200005];
int cnt,n,m;
int dist[20005];
int flag[20005];
queue<int> q;
struct Edge{
int v,next,w;
}edge[200005];
void add_edge(int u,int v,int w){//星图存储
cnt++;
edge[cnt].v = v;
edge[cnt].next = head[u];
edge[cnt].w = w;
head[u] = cnt;
}
void Spfa(int t)
{
memset(dist,127,sizeof(dist));
memset(flag,0,sizeof(flag));
dist[t]=0;
flag[t]=1;
q.push(t);
while(!q.empty()){
int v = q.front();
q.pop();
flag[v]=0;
for(int i=head[v];i>0;i=edge[i].next){ //遍历星图
if(dist[edge[i].v]>edge[i].w+dist[v]){
dist[edge[i].v]=edge[i].w+dist[v];
if(!flag[edge[i].v]){
q.push(edge[i].v);
flag[edge[i].v]=1;
}
}
}
}
for(int i=1;i<=n;i++){ //输出
if(i!=t){
cout<<dist[i]<<endl;
}
}
}
int main()
{
int u,v,w;
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>u>>v>>w;
add_edge(u,v,w);
}
Spfa(1);
}
说明
对于10%的数据,n = 2,m = 2。
对于30%的数据,n <= 5,m <= 10。
对于100%的数据,1 <= n <= 20000,1 <= m <= 200000,-10000 <= l <= 10000,保证从任意顶点都能到达其他所有顶点。