作用:源点到i点的最短距离(最*权值)。
算法:本质上是BFS,但利用邻接表来处理点与点之间的关系,处理量更大 ;
前向星是一个数组模拟的头插法链表,再处理上比vector快。
代码
时间复杂度 : O(|V|*|E|) ,最坏情况下
输入 : N(点的数量) M(边的数量) src(源点)
X Y(边) w(权值)
输出 : dist[i] 源点到各点之间的最短距离
const int MaxN=100010;//边的最大数量
struct node
{
int next,to,w;
};
node edge[MaxN];
int head[MaxN],cnt;//以上为构造链式前向星时所要用到的工具
int vis[MaxN];//验证点是否在队列里
int dist[MaxN];//存储距离
queue<int>Q;
void init()//初始化函数
{
memset(head,-1,sizeof(head));//只能设为-1
memset(vis,0,sizeof(vis));
memset(dist,63,sizeof(dist));
cnt=0;
while(!Q.empty()) Q.pop();
}
void add(int u,int v,int w)//前向星存表
{
edge[cnt].w=w;
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt++;
}
void SPFA(int x)
{
Q.push(x);
dist[x]=0;
vis[x]=1;
while(!Q.empty())
{
int temp=Q.front();
Q.pop();
vis[temp]=0;
for(int i=head[temp];i!=-1;i=edge[i].next)//链式遍历
{
int u=edge[i].to;
int w=edge[i].w;
if(dist[u]>dist[temp]+w)
{
dist[u]=dist[temp]+w;
if(!vis[u])
{
Q.push(u);
vis[u]=1;
}
}
}
}
}
int main()
{
int N,M,src;//节点的个数,边的个数,源点
while(cin>>N>>M>>src)
{
int x,y,z;
init();//初始化
for(int i=0; i<M; ++i)
{
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);//链式前向星存储
//add(y,x,z);//当图为无向图或其他情况时
}
SPFA(src);
for(int i=1;i<=N;++i)//源点到每个点的最短距离
printf("%d\n",dist[i]);
}
return 0;
}