dijkstra基本操作
/*
6个顶点 8条边 起点为0
0->1 权值为1
下同
6 8 0
0 1 1
0 3 4
0 4 4
1 3 2
2 5 1
3 2 2
3 4 3
4 5 3
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
#define MAX 1000 //最大结点数
#define INF 100000000
using namespace std;
int adt[MAX][MAX];
int n,m,s;//n结点数 m边数 s起点
int dis[MAX];//起点到各点的最短路径长度
bool vis[MAX]={false};
int pre[MAX];//pre[v]表示从起点到结点v的最短路径上,v的前一个结点(前驱)
void dijkstra(int s)
{
fill(dis,dis+MAX,INF);
dis[s]=0;
for(int i=0;i<n;i++)
{
int u=-1; //u使d[u]最小
int min=INF;//min存放最小的 d[u]
for(int j=0;j<n;j++)
{
if(vis[j]==false&&dis[j]<min)//找为访问顶点中dis[]最小的
{ //第一次执行时 vis[]默认都为 false
u=j;
min=dis[j];
}
}
//找不到小于INF的d[u]说明剩下的顶点都与起点s不通
//dijkstra终止条件
if(u==-1)return;
vis[u]=true;
for(int v=0;v<n;v++)
{
//v未被访问 && u能到达v && 以u为中介点可以使得d[v]更优
if(vis[v]==false&&adt[u][v]!=INF&&dis[u]+adt[u][v]<dis[v])
{
dis[v]=dis[u]+adt[u][v];//优化操作
pre[v]=u;//记录v的前驱结点是u
}
}
}
}
//s为起点 v为要访问的顶点编号
void dfs(int s,int v)
{
if(v==s)//已经到达起点s 输出起点并返回
{
cout<<s<<" ";
return;
}
dfs(s,pre[v]);//递归访问v的前驱顶点 pre[v]
//从最深处 return回来之后,输出每一层顶点号
cout<<v<<" ";
}
int main()
{
cin>>n>>m>>s;
// #include<algorithm>
fill(adt[0],adt[0]+MAX*MAX,INF);
for(int i=0;i<m;i++)
{
int a,b,c;cin>>a>>b>>c;
adt[a][b]=c;
}
dijkstra(s);
for(int i=0;i<n;i++)
cout<<dis[i]<<" ";
cout<<endl;
for(int i=0;i<n;i++)
{
if(i==s)
{
cout<<"the distance start node s to itself is 0"<<endl;
continue;
}
printf("distance:%d %d->%d: ",dis[i],s,i);
dfs(s,i);//print shortest path
cout<<endl;
}
}