【模板】单源最短路径
题目
如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度。
Input
第一行包含三个整数n,m,s分别表示点的个数、有向边的个数、出发点的编号。
接下来m行每行包含三个整数u,v,w表示一条u→v的,长度为w的边。
Output
输出一行n个整数,第i个表示s到第i个点的最短路径,若不能到达则输出231-1。
Sample Input
4 6 1
1 2 2
2 3 2
2 4 1
1 3 5
3 4 3
1 4 4
Sample Output
0 2 4 3
解析
这题就是spfa上手题
n<=104,所以不打dij(什么?堆优化dij?不嫌麻烦?),选择spfa
需要注意的是比赛时最好还是用堆优化+dij,不要打spfa,极易被卡掉
2018NOID1T1归程
一遍打过,不调就A真不错
code:
#include<queue>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m,s,x,y,z,head[10010],ans[10010],tot=0,k;
struct f
{
int to,w,nxt;
}a[500010];//邻接表
void add(int x,int y,int z)
{
a[++tot].to=y,a[tot].w=z,a[tot].nxt=head[x],head[x]=tot;
}
bool u[10010];
queue <int> b;
void spfa()//spfa核心代码
{
while(!b.empty())
{
k=b.front(),b.pop();
u[k]=0;
for(int i=head[k];i;i=a[i].nxt)
{
if(a[i].w+ans[k]<ans[a[i].to])
{
ans[a[i].to]=ans[k]+a[i].w;
if(!u[a[i].to])
{
u[a[i].to]=1;
b.push(a[i].to);
}
}
}
}
for(int i=1;i<=n;i++)
{
if(ans[i]==0x7f7f7f7f)printf("2147483647 ");//不要直接设初值为2147483647,不然会溢出
else printf("%d ",ans[i]);
}
}
int main()
{
memset(ans,0x7f7f7f7f,sizeof(ans));
scanf("%d%d%d",&n,&m,&s);
while(m--)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);//有向图建一条边
}
u[s]=1,ans[s]=0,b.push(s);//初始化
spfa();
return 0;
}