最短路
题目描述
简单暴力的题目要求:
给定一个有n个顶点(从1到n编号),m条边的有向图(其中某些边权可能为负,但保证没有负环)。请你计算从1号点到其他点的最短路。
输入描述:
第一行两个整数n, m。
接下来的m行,每行有三个整数u, v, l,表示u到v有一条长度为l的边。
输出描述:
共n-1行,第i行表示1号点到i+1号点的最短路。
示例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,保证从任意顶点都能到达其他所有顶点。
AC代码:
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int N=200005;
const int INF=0x3f3f3f3f;
int n,m,u,v,l;
int dis[N];
bool vis[N];
vector<pair<int,int>> con[N];
void SPFA(int s){
for(int i=2;i<=n;++i)
dis[i]=INF;
dis[s]=0,vis[s]=true;
queue<int> que;
que.push(s);
while(!que.empty()){
int num=que.front();
que.pop();
vis[num]=false;
for(int i=0;i<con[num].size();++i){
int to=con[num][i].first,w=con[num][i].second;
if(dis[to]>dis[num]+w){
dis[to]=dis[num]+w;
if(!vis[to]){
que.push(to);
vis[to]=true;
}
}
}
}
}
int main(){
cin>>n>>m;
for(int i=0;i<m;++i){
cin>>u>>v>>l;
con[u].push_back({v,l});
}
SPFA(1);
for(int i=2;i<=n;++i)
if(dis[i]<INF/2)
printf("%d\n",dis[i]);
}
总结
用Floyd会导致内存超限,代码还可以用链式前向星浅浅优化一下,但一般用邻接表就能过。