您的位置:首页 > 其它

[洛谷]P3371 单源最短路径模板 SPFA

2017-11-02 18:13 218 查看
#include<cstdio>

#include<cstring>

#include<iostream>

using namespace std;

#define maxn 500005

struct nod{
int to,next,val;

}a[maxn];

int node=0;

int vis[maxn],dis[maxn],head[maxn],queue[maxn];

int n,m,s;

inline void iint() //初始化操作,head[i]=-1 表示这条边已是最后一条边
{
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=m;i++)
head[i]=-1;
}

inline void add(int u,int v,int w) //建图加边
{
a[++node].to=v;  //这条边指向的点
a[node].val=w;  //这条边的权值
a[node].next=head[u]; //与这条边有共同端点的下一条边
head[u]=node;
//道理同上
}

inline void spfa() //spfa算法,广度优先算法
{
int l=0,u,r=1; //l,r分别表示队列的头和尾
queue[1]=s; //第一个点入队
dis[s]=0;/*这个点的最短路径*/ vis[s]=1; //将这个点入队
while(l<r)
{
u=queue[++l]; 
vis[u]=0; //出列操作
for(int i=head[u];i!=-1;i=a[i].next)//遍历以这个点为端点的所有边
{
if(dis[a[i].to]>dis[u]+a[i].val) 
{
dis[a[i].to]=dis[u]+a[i].val;
if(vis[a[i].to]==0) //如果到达的点不在队列中
{
vis[a[i].to]=1;  
queue[++r]=a[i].to;//入队
}
}
}
}
}

int main()
{
scanf("%d%d%d",&n,&m,&s);
iint();
int x,y,z;
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);

}
spfa();
for(int i=1;i<=n;i++)
{
if(dis[i]==0x3f3f3f3f)  //最大值,表示初始点无法到达这个点
cout<<"2147483647 ";
else cout<<dis[i]<<" ";   
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: