最短路径的实现(简化版)

  这里运用了Dijkstra算法

/**
 * 邻接矩阵表示的有向图的Dijkstra(单源最短路径)算法
 * 顶点节点编号默认范围为[0,N-1]!即N个顶点编号不允许取到N
 */ 
#include<iostream>

#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define Max 1000   //最大点编号
int Map[Max][Max];  //图的邻接矩阵表示
int flag[Max];      //顶点访问标记
int ans[Max];       //记录各点指定点距离
int S,E;            //起点终点
int N,M;            //节点数和边数
void Dijkstra()
{
    memset(flag,0,sizeof(flag));
    memset(ans,0x3f,sizeof(ans));//置无穷 
    ans[S]=0;//起点置零 
    while(true)
    {
        int v=-1;  //标记目前访问结点
        for(int u=0;u<N;u++)  //遍历所有顶点,找到当前 未访问过 且 离起点源最近 的节点
        {
            if(!flag[u]&&(v==-1||ans[u]<ans[v]))//一次访问 
                v=u;
        }
        if(v==-1) return;  //所有顶点都访问完成,则完成最短路径计算
        flag[v]=1;  //访问标记
        for(int i=0;i<N;i++)  //计算更新目前所有访问过顶点的最短路径,即比较 目前访问节点带来的路径 和 之前记录的最短路径
            {
            if(i != v && Map[v][i] != INF)
			ans[i]=min(ans[i],ans[v]+Map[v][i]);
            //cout<<ans[i]<<endl;
            }
    }
}
int main()
{
    cin>>N>>M>>S;
	S=S-1;                       //输入顶点数和边数
    memset(Map,0x3f,sizeof(Map));    //初始化图
    for(int i=1;i<=M;i++)            //输入每条边
    {
        int u,v,cost;
        cin>>u>>v;
         //考虑题目可能同边不同值,只取最短边
            Map[u-1][v-1]=1;
			Map[v-1][u-1]=1;  //无向图的话再令Map[v][u]=cost即可
    }
    Dijkstra();
    for(int i=0;i<N;i++)
        cout<<ans[i]<<endl;   
}

Map记录了邻接矩阵(带权值)

flag访问标记

N M分别为点数和边数

S起点 E终点

//主要代码
void Dijkstra(){
	memset(flag,0,sizeof(flag));
	memset(ans,INF,sizeof(ans));//最短路径赋值
	ans[S]=0;//到自己的值为0
	while(true){
		int v=-1;//当前节点
		for(int u=0;u<N;u++){
			if(!flag[u]&&(v==-1)||ans[u]<ans[v]){//找到未放问过的且离点源最近 
				v=u;
			}
			if(v==-1) return ;//全部节点访问完 
			flag[v]=1;
		}
		//更新最短路径
		for(int i=0;i<N;i++){
			if(v!=-1&&Map[v][i]!=INF){
				ans[i]=min(ans[i],ans[v]+Ma[v][i]);
			}
		} 
	} 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值