链式向前星 https://blog.csdn.net/qq_30331643/article/details/68621435
模板题 洛谷3371.
//优化输入的
#include<bits/stdc++.h>
using namespace std;
#define maxn 10005
#define maxm 500005
#define INF 2147483647
inline int read(){
int x=0,k=1; char c=getchar();
while(c<'0'||c>'9'){if(c=='-')k=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*k;
}
struct Edge
{
int u,v,w,next;
}edge[maxm];
int head[maxm],cnt,n,m,s,vis[maxn],dis[maxn];
#define P pair<long long,int>
priority_queue<P,vector<P>,greater<P> >q;
//把最小的元素放在队首的优先队列
inline void add(int u,int v,int w)
{
edge[++cnt].u=u;
//这句话对于此题不需要,但在缩点之类的问题还是有用的
edge[cnt].v=v;
edge[cnt].w=w;
edge[cnt].next=head[u];
//存储该店的下一条边
head[u]=cnt;
//更新目前该点的最后一条边(就是这一条边)
}
//链式前向星加边
void dijkstra()
{
for(int i=1;i<=n;i++)
{
dis[i]=INF;
}
dis[s]=0;
//赋初值
q.push(make_pair(0,s));
while(!q.empty())
//堆为空即为所有点都更新
{
int x=q.top().second;
q.pop();
//记录堆顶并将其弹出
if(!vis[x])
//没有遍历过才需要遍历
{
vis[x]=1;
for(int i=head[x];i;i=edge[i].next)
//搜索堆顶所有连边
{
int v=edge[i].v;
dis[v]=min(dis[v],dis[x]+edge[i].w);
//松弛操作
q.push(make_pair(dis[v],v));
}
}
}
}
int main()
{
n=read(),m=read(),s=read();
for(int i=1;i<=m;i++)
{
int x,y,z;
x=read(),y=read(),z=read();
add(x,y,z);
}
dijkstra();
for(int i=1;i<=n;i++)
{
printf("%d ",dis[i]);
}
return 0;
}
再来一个Floyd
//Floyd
typedef struct
{
char vertex[VertexNum]; //顶点表
int edges[VertexNum][VertexNum]; //邻接矩阵,可看做边表
int n,e; //图中当前的顶点数和边数
}MGraph;
void Floyd(MGraph g)
{
int A[MAXV][MAXV];
int path[MAXV][MAXV];
int i,j,k,n=g.n;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
A[i][j]=g.edges[i][j];
path[i][j]=-1;
}
for(k=0;k<n;k++)
{
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(A[i][j]>(A[i][k]+A[k][j]))
{
A[i][j]=A[i][k]+A[k][j];
path[i][j]=k;
}
}