luogu3371.单源最短路径。
一道模版至极的模版题。
给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
数据规模:时空限制:1000ms,128M
对于20%的数据:N<=5,M<=15
对于40%的数据:N<=100,M<=10000
对于70%的数据:N<=1000,M<=100000
对于100%的数据:N<=10000,M<=500000
还不是很懂spfa时间复杂度怎么求,在现学过的算法里,我朴素的floyed和dijkstra是毫无疑问会稳定地TLE的,所以还是不管三七二十一上了bellman-ford,居然能过……
下面是我历经风霜坎坷、跋山涉水、远道而来的代码。
(可以说是非常之惨了)
#include<bits/stdc++.h>
using namespace std;
struct edge
{
int q,z,v;
}e[500001];//边表。
int n,m,s;//点数、边数、起点。
int dis[500001]={};
void bmf()
{
for(int i=1;i<=n;i++) dis[i]=100000;//先全赋初值。
dis[s]=0;
for(int i=1;i<=n;i++)
{
int flag=0;
for(int j=1;j<=m;j++)
{
if(dis[e[j].z]>dis[e[j].q]+e[j].v)
dis[e[j].z]=dis[e[j].q]+e[j].v,flag=1;
}
if(flag==0) break;
}
return;
}//标准的bmf。
int main()
{
scanf("%d%d%d",&n,&m,&s);
for(int i=1;i<=m;i++)
{
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
e[i].z=y;e[i].q=x;e[i].v=v;//呵呵,是有向图,有向图,有向图,……
}
bmf();
for(int i=1;i<=n;i++)if(dis[i]!=100000)printf("%d ",dis[i]);
else printf("2147483647 ");//一个特判,具体看下面……
return 0;
}
之所以说它历经风霜,是因为一开始这道题我的程序(在赋初值那一步直接赋了2147483647,结尾直接输出)会输出负数,万分迷茫的我查了三刻钟的错,后来才知道是没有“正数相加输出负数多半是溢出”这个基本常识,……。因为2147483647是个很大的数了,在计算路径的时候一加二加三四加就容易爆炸。最后,谢谢sj的特判赞助。