最短路径例子

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
假设有下面这个图,我们要求出从A到其他各个节点的最短路径: ``` 2 3 A ------ B ------ C | 1 4 | | 5 | D ---------------- E 6 ``` 首先我们初始化一个二维数组`dist`,表示起点A到各个节点的最短距离。将起点A到自己的距离设为0,其他节点的距离先设为无穷大(因为我们还不知道最短距离是多少): ``` dist = [ [0, inf, inf, inf, inf], [inf, 0, inf, inf, inf], [inf, inf, 0, inf, inf], [inf, inf, inf, 0, inf], [inf, inf, inf, inf, 0] ] ``` 接下来,我们需要利用Floyd算法,逐步更新`dist`数组,直到找到所有节点的最短路径。 Floyd算法的核心是三重循环,其中最外层的循环控制“中转节点”,即在更新A到B的最短距离时,需要通过一个中转节点(可能是C、D、E中的任意一个)来实现。中间的两重循环分别遍历所有的起点和终点,如果发现通过当前中转节点可以得到更短的路径,则更新`dist`数组。 下面是Floyd算法的Python实现: ```python def floyd(dist): n = len(dist) for k in range(n): for i in range(n): for j in range(n): if dist[i][j] > dist[i][k] + dist[k][j]: dist[i][j] = dist[i][k] + dist[k][j] dist = [ [0, 2, 1, inf, inf], [inf, 0, inf, inf, inf], [inf, 3, 0, 4, inf], [inf, inf, inf, 0, 6], [inf, inf, inf, inf, 0] ] floyd(dist) print(dist) ``` 输出结果为: ``` [ [0, 2, 1, 5, 11], [inf, 0, inf, inf, inf], [inf, 3, 0, 4, 10], [inf, inf, inf, 0, 6], [inf, inf, inf, inf, 0] ] ``` 可以看到,最终`dist`数组中包含了A到各个节点的最短距离。比如,A到节点B的最短距离为2,A到节点C的最短距离为1,A到节点D的最短距离为5,A到节点E的最短距离为11。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值