中易网

编写的迪杰斯特拉算法求最短路径,运行不正确?

答案:1  悬赏:30  
解决时间 2021-02-11 05:10
编写的迪杰斯特拉算法求最短路径,运行不正确?
最佳答案
鉴于最小生成树和最短路径的dijkstra是相似的,我把它们合到一块了,另外下面附了一个用堆优化的dijkstra(优先队列)的代码,看看吧。

最小生成树的普利姆算法和求最短路径的dijkstra算法
算法思想:
1.、先将出发点(对最小生成树来说可以是任意一点)放入集合s中(s为元素为图的顶点的集合,记录已经解决的顶点)。
2、找到s外的所有点到s的距离(即到s中所有点的距离的最小值)最小的点,把这一点加入s集合。
3、由于新加入的一个点会使某些点到s的距离更短,更新s外的其他点到集合s的距离(如果可以更短,则更新之)。
4、返回执行第2步,直到所有的点都加入s中。
注:第二步找到的最短距离会逐步增加,所以此算法也可以解决例如第K远的城市这种问题
算法代码:
int const MAXN = 100;
int i,j;

int n; //记录图的顶点个数

int edge[MAXN][MAXN]; //记录各边权值, 默认无向并且已知,两点之间无边则记为无穷大

int dist[MAXN]; //记录当前各个点到集合s的最小距离,在运行过程中不断更新

int s[MAXN] = {0}; //记录已经解决的点的下标,标志着该顶点是否加入最小生成树

//初始化,假设各边权值已知,出发点为0
for(i = 0; i < n; i++)
{
dist[i] = edge[0][i];
}


s[0] = 1;

for(i = 0; i < n - 1; i++)//循环n-1次将剩余的n-1个点加入生成树
{

int min = inf; // inf 为可能的最大值
int u = 0; // 记录距离s最短的顶点的下标
for(j = 0; j < n; j++)
{
if(!s[j] && dist[j] < min)
{
min = dist[j];
u = j;
}
}
s[u] = 1;


for(j = 0; j < n; j++)
{
if(!s[j] && edge[u][j] < dist[j])
dist[j] = edge[u][j];
}



for(j = 0; j < n; j++)
{
if( !s[j] && dist[u] + edge[u][j] < dist[j])
dist[j] = dist[u] + edge[u][j];
}

}

附:


#include <iostream>
#include <queue>
using namespace std;

const int MAXN = 110;

int head[MAXN],size;
int dist[MAXN];
int n;

struct enode{
int v,cost,next;
enode(){}
enode(int _v,int _cost):v(_v),cost(_cost){}
enode(int _v, int _cost, int _next):v(_v), cost(_cost), next(_next){}
bool operator < (const enode &t) const{
return cost > t.cost;
}
};
enode edges[MAXN*MAXN];

void add_edge(int u,int v,int cost){
edges[size] = enode(v,cost,head[u]);
head[u] = size++;
}

int init(){
int m,u,v,c;
memset(head,-1,sizeof(head));
size = 0;
scanf("%d%d",&n,&m); //输入顶点数和边数
if(m == 0 && n == 0)return 0;
for(int i = 0; i < m; i++){
scanf("%d%d%d",&u,&v,&c); //输入边的两个顶点和边的权值
add_edge(u-1,v-1,c);
add_edge(v-1,u-1,c);
}
return 1;
}

void Dijkstra(int st){

memset(dist,0x3f,sizeof(dist));
dist[st] = 0;

priority_queue < enode > q;
q.push( enode(st,0) );
while ( !q.empty() ){

enode top = q.top();
q.pop();

if(top.cost != dist[top.v]) continue;

int u,v;
u = top.v;
for(int i = head[u] ;i != -1; i = edges[i].next){
v = edges[i].v;
if ( dist[v] > dist[u] + edges[i].cost ){

dist[v] = dist[u] + edges[i].cost;
q.push( enode(v,dist[v]) );
}
}
}
}

int main(){
while( init() ){
Dijkstra(0);
printf("%d\n",dist[n-1]);
}
return 0;
}
我要举报
如以上问答内容为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
美的空调线被老鼠咬断显示E3接好后显示E2是什
大家都不要买苏泊尔的锅
建筑用水量计算是用来确定什么的?
高品格单恋女主成为明星了吗?
湖州南浔供水在哪里啊,我有事要去这个地方
香泉镇第一汤怎么样
有谁知道阉鸡,阉下来的那个东西叫什么。求学
我想买个东方红拖拉机灭茬子不知道多大马力的
同一个手机卡能登两个本人的微信号吗?
乐堡士(隆尧店)地址在什么地方,想过去办事
为什么2006年喀纳斯邮票这么贵
为什么都说选择一个你爱的人、不如选择一个爱
阿卫农家乐这个地址在什么地方,我要处理点事
红米1s官方的recovery刷官方的rom包 怎么也刷
我广发银行信用卡审批通过才3000元怎么那么少
推荐资讯
三月份为什么老是下雨
北京高档衣服哪里洗
”依然”这两个字怎么写更好看,怎么样繁体才
广安市武胜县烈面镇地址在哪,我要去那里办事
请问在外协制作皮带轮时皮带轮轮槽的具体尺寸
盛溢日杂总汇地址在什么地方,想过去办事
哪一首歌里有一个词是 格格巫
我想问下岳阳东城小学的招生片区是那些,我妹
在日本,参加丧礼应该送什么
河畔华苑二期怎么去啊,有知道地址的么
小米手环2,触摸按键有时不管用,怎么回事
求圈名,用于盗墓,古风圈
手机登qq时,显示手机磁盘不足,清理后重新登
刺客的套装怎么选啊?