最短路径例子

#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 ()算法 ,其中迭代过程中一定要注意判断 这个点是不是已经进入整个图中。第一个算法与第二个算法的区别在与 是不是将初始点作为进行迭代的点。这一点不同后数组的初始化也会不同的地方

Guess you like

Origin blog.csdn.net/weixin_44724691/article/details/107759684