版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/leekerian/article/details/87924612
dijkstra求原点到终点的最短路径,用数组标记前继
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN=555;
const int INF=0x3fffffff;
int n,m;
int map[MAXN][MAXN],vis[MAXN],val[MAXN],path[MAXN],
pathnum[MAXN],dis[MAXN],totval[MAXN];
void Dijkstra(int s)
{
for(int i=0;i<n;i++)
dis[i]=INF;
vis[s]=1;
dis[s]=0;
totval[s]+=val[s];
pathnum[s]=1;
for(int i=0;i<n;i++)
{
if(!vis[i]&&i!=s)
{
if(map[s][i]!=INF)
{
dis[i]=map[s][i];
path[i]=s;
pathnum[i]=1;
totval[i]=val[s]+val[i];
}
}
}
for(int i=0;i<n-1;i++)
{
int u,mind=INF;
for(int j=0;j<n;j++)
{
if(dis[j]<mind&&!vis[j])
{
mind=dis[j];
u=j;
}
}
vis[u]=1;
for(int j=0;j<n;j++)
{
if(!vis[j])
{
if(dis[u]+map[u][j]<dis[j])
{
dis[j]=dis[u]+map[u][j];
totval[j]=totval[u]+val[j];
path[j]=u;
pathnum[j]=pathnum[u];
}
else if(dis[u]+map[u][j]==dis[j])
{
dis[j]=dis[u]+map[u][j];
if(totval[j]<totval[u]+val[j])
{
totval[j]=totval[u]+val[j];
path[j]=u;
}
pathnum[j]+=pathnum[u];
}
}
}
}
}
int main()
{
int s,d;
scanf("%d%d%d%d",&n,&m,&s,&d);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
map[i][j]=INF;
memset(vis,0,sizeof(vis));
memset(totval,0,sizeof(totval));
for(int i=0;i<n;i++)
scanf("%d",&val[i]);
for(int i=0;i<m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
map[x][y]=z;
map[y][x]=z;
}
Dijkstra(s);
int cont=0;
int ans[MAXN];
int cur=d;
while(cur!=s)
{
ans[cont++]=cur;
cur=path[cur];
}
ans[cont++]=s;
printf("%d %d\n",pathnum[d],totval[d]);
for(int i=cont-1;i>0;i--)
printf("%d ",ans[i]);
printf("%d\n",ans[0]);
return 0;
}