#include<iostream>
#include<stack>
using namespace std;
#define INF 0xffffff
int n,m,c1,c2;
int edge[510][510];
int weight[510];
int dist[510];
int num[510];
int w[510];
int s[510]; //存储已访问的点集
int path[510];
void Dijkstra(int v)
{
fill(dist, dist + 510, INF);
dist[v]=0;
//s[v]=1;
w[v]=weight[v];
num[v]=1;
path[v]=-1;
for(int i = 0;i<n;i++)
{
int u = -1,minx = INF;
for(int j = 0;j<n;j++)
{
if(minx>dist[j]&&s[j]==0) //在没加入到s集合中的点中寻找dist最小的点
{
u = j;
minx = dist[j];
}
}
if(u ==-1) break; //不连通终止
s[u] = 1; //将点u加入s集合
for(int j = 0;j<n;j++)
{
if(s[j]==0&&edge[u][j]!=INF)
{
if(dist[u]+edge[u][j]<dist[j])
{
dist[j] = dist[u]+edge[u][j];
num[j] = num[u];
w[j] = w[u]+weight[j];
path[j]=u;
}
else if(dist[u]+edge[u][j]==dist[j])
{
num[j] = num[j]+num[u];
if(w[u]+weight[j]>w[j]){
w[j] = w[u]+weight[j];
path[j]=u;
}
}
}
}
}
}
int main()
{
cin>>n>>m>>c1>>c2;
for(int i = 0;i<n;i++)
cin>>weight[i];
//edge初始化
for(int i = 0;i<n;i++)
for(int j = 0;j<n;j++)
edge[i][j] = INF;
for(int i = 0;i<m;i++)
{
int a,b,l;
cin>>a>>b>>l;
edge[a][b] = edge[b][a] = l;
}
Dijkstra(c1);
cout<<num[c2]<<" "<<w[c2]<<endl;
//利用栈输出路径
stack<int>ss;
ss.push(c2);
while(path[c2]!=0)
{
ss.push(path[c2]);
c2=path[c2];
}
cout<<c1;
while(!ss.empty())
{
cout<<" "<<ss.top();
ss.pop();
}
return 0;
}
#include<bits/stdc++.h>
using namespace std;
#define inf 1000000
int a[1001][1001];
int cnt[1001],exs[1001]={
0},cf[1001],ccf[1001],pre[1001];
//最短路径条数,各城市是否经过,各城市的救援队数量,到达该城市时所召集的所有救援队数量,到达该城市前经过的城市编号
int n,m,s,d;
int Dijkstra()
{
cnt[s]=1;//开始时路径条数为1
exs[s]=1;//当前在出发城市
for(int i=0;i<n;i++){
int min=inf,f=-1;
for(int j=0;j<n;j++){
if(exs[j]==0&&a[s][j]<min){
//寻找下一个距离最短的城市
cout<<"a["<<s<<"]["<<j<<"] is finding !!"<<endl;
min=a[s][j];
f=j;//做好下一城市编号的标记
}
cout<<" min _pos is :"<<f<<endl;
}
if(f==-1)break;//与其他未经过的城市不连通,退出循环
else exs[f]=1;//到达下一城市
for(int j=0;j<n;j++){
if(exs[j]==0&&a[s][j]>a[s][f]+a[f][j]){
//到达某一城市的最短路径
cout<<"1"<<endl;
cout<<" s is :"<<s<<" j is :"<<j<<" f is :"<<f<<endl;
a[s][j]=a[s][f]+a[f][j];//最短路径更新
pre[j]=f;//记录上一个城市编号
cnt[j]=cnt[f];//拷贝到达上一个城市时的最短路径条数
ccf[j]=ccf[f]+cf[j];//到达某城市召集的全部救援队数量
}
else if(exs[j]==0&&a[s][j]==a[s][f]+a[f][j]){
//发现其他的最短路径
cout<<"2"<<endl;
cout<<" s is :"<<s<<" j is :"<<j<<" f is :"<<f<<endl;
cnt[j]=cnt[j]+cnt[f];//更新到达当前城市时的最短路径条数
if(ccf[j]<ccf[f]+cf[j]){
//最多救援队数量更新
pre[j]=f;//记录所经过的上一个城市编号
ccf[j]=ccf[f]+cf[j];//更新救援队总数
}
}
}
}
}
int main()
{
cin>>n>>m>>s>>d;
for(int i=0;i<n;i++){
cin>>cf[i];
ccf[i]=cf[i];
cnt[i]=1;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(i!=j)a[i][j]=a[j][i]=inf;//初始化(双向图)
}
}
for(int i=0;i<m;i++){
int q,w,e;
cin>>q>>w>>e;
a[q][w]=a[w][q]=e;
}
Dijkstra();
cout<<cnt[d]<<" "<<ccf[d]+cf[s]<<endl;
int road[1001];
int x=0,t=d;
while(pre[t]!=0){
//所经历的城市的从后往前的顺序
road[x++]=pre[t];
t=pre[t];
}
cout<<s;//出发地
for(int i=x-1;i>=0;i--)
cout<<" "<<road[i];
cout<<" "<<d;//目的地
}
以上的两个例子 都是用了dijkstra ()算法 ,其中迭代过程中一定要注意判断 这个点是不是已经进入整个图中。第一个算法与第二个算法的区别在与 是不是将初始点作为进行迭代的点。这一点不同后数组的初始化也会不同的地方