链式前向星储存图
主要有一个边数组和一个头数组(最近一次输入的以i为起点在边数组中的下标)组成。
代码:
truct node{
int to;//第i条边的终点
int w;/第i条边的权值
int next;//与第i条边同起点的下一条边的位置
}edge[Maxn];//边数组
int head[Maxn];
void add(int u,int v,int w){
edge[cnt].to=v;//cnt为edge索引
edge[cnt].w;
edge[cnt].next=head[u]
//类似头插法,先取得头节点的后息,再更新头节点
head[u]=cnt++;/更新头节点
}
P4779 【模板】单源最短路径(标准版)
P4779 【模板】单源最短路径(标准版) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
使用dijkstra算法来解决,这里还需要用到优先队列来进行优化,优化的地方在于dijkstra算法每次都需要找到一个没访问的最小值所以用优先队列。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int head[100100],num,vis[100100];
ll ans[100100];
struct node{
int to;
int next;
int w;
}e[1000010];
struct priority{
ll ans;
int id;
bool operator <(const priority &x)const//改为小顶堆存放
{
return x.ans<ans;
}
};
priority_queue<priority>q;
int n,m,s,i;
void add(int from,int to,int w);
void djst();
int main()
{
cin>>n>>m>>s;
for(i=1;i<=n;i++)ans[i]=2147483647;//初始化ans数组
ans[s]=0;
for(i=1;i<=m;i++)
{
int u,v,w;
cin>>u>>v>>w;
add(u,v,w);
}
djst();
for(i=1;i<=n;i++){
cout<<ans[i]<<' ';
}
}
void add(int from,int to,int w)//链式前向星储存
{
e[++num].to=to;
e[num].next=head[from];
e[num].w=w;
head[from]=num;
}
void djst()
{
int mini;
q.push((priority){0,s});//入队初始位置
while(!q.empty()){//当队列为空时终止说明已经访问完了
priority t=q.top();//队顶的最小元素
q.pop();
mini=t.id;
if(vis[mini]==0)
{
vis[mini]=1;
for(i=head[mini];i;i=e[i].next)
{
if(!vis[e[i].to]&&ans[mini]+e[i].w<ans[e[i].to])
ans[e[i].to]=ans[mini]+e[i].w;
if(vis[e[i].to]==0)
q.push((priority){ans[e[i].to],e[i].to});//加入更新的地方
}
}
}
}