dijstra算法

自己用到了,所以就看了下输完,写了个,输出最短路径,还有父节点。


#include<iostream>
#include<vector>


#define MAX 1000
using namespace std;


struct  edge
{
   int tail;
   int head;     
   float weight;   //改边的权值
};

 void dijstra_KSP(int nnodes,vector<edge>&edges,int end);


int main()
{   
int nnodes=5;
int nedges=10;
vector<edge>edges(nedges);
edges[0].tail=0;edges[0].head=1;edges[0].weight=10;
edges[1].tail=0;edges[1].head=2;edges[1].weight= 5;
edges[2].tail=1;edges[2].head=2;edges[2].weight=2;
edges[3].tail=1;edges[3].head=4;edges[3].weight=1;
edges[4].tail=2;edges[4].head=1;edges[4].weight=3;
edges[5].tail=2;edges[5].head=3;edges[5].weight=2;
edges[6].tail=2;edges[6].head=4;edges[6].weight=9;
    edges[7].tail=3;edges[7].head=0;edges[7].weight=7;
    edges[8].tail=3;edges[8].head=4;edges[8].weight=6;
edges[9].tail=4;edges[9].head=3;edges[9].weight=4;

dijstra_KSP(nnodes,edges,0);
cin.get();
   return 0;
}






//dijstra单源点最短路径,  
 void dijstra_KSP(int nnodes,vector<edge>&edges,int end)
{
   //把图中边转置,tail--->head   ===>>  head-->tail
vector<edge>::iterator vi;
/*for(vi=edges.begin();vi!=edges.end();vi++)
{
   int temp;
temp=vi->head;
vi->head=vi->tail;
vi->tail=temp;
}*/
vector<int>parent(nnodes);
bool mark[MAX];
vector<float>d(nnodes);     //记录最短路径


for(int i=0;i<nnodes;i++)    //初始化 节点序号从0开始
{
  d[i]=-1;
  mark[i]=false;
  parent[i]=-1;
}


d[end]=0;
mark[end]=true;
int newp=end;        //加入集合K

for(int i=1;i<nnodes;i++)   //循环nnodes-1次
{
for(vi=edges.begin();vi!=edges.end();vi++)    //遍历与新加入集合K中的节点直接相邻的边
{
if(vi->tail==newp)   //由这条边发出去的
{
int head=vi->head;
float weight=vi->weight;
if(mark[head]==true)      //如果另外一条边也属于K,跳过
continue;
if(d[head]==-1||d[head]>d[newp]+weight)
 {
 d[head]=d[newp]+weight;                     //更新起最短距离
 parent[head]=vi->tail;                           //保存这个节点的的父节点
}
}
}


float min=123123123;                    //初始化为一个大整数为找最小值做准备
for(int j=0;j<nnodes;j++)   //遍历所有节点,搜索通过K中节点所到达的是最短距离的节点,作为newP
{
 if(mark[j]==true)     //若其属于集合K,跳过
 continue;
 if(d[j]==-1)              //若该节点仍不可达,跳过
 continue;   
 if(d[j]<min)                //若该节点经由节点end至集合K中的某节点在经过一条边达到是距离小于当前最小值,更新为最小值,新加入的节点暂定为最小值
 {
    min=d[j];
newp=j;
 }
}
mark[newp]=true;   //将新加入的点加入集合K,d[newp]虽然数值不变,但意义发生变化,由所有经过集合K中的节点再经过一条边到达时的距离中的最小值变为从节点end到节点newp的最短距离。


}
for(int j=0;j<nnodes;j++)
cout<<d[j]<<endl;
for(int j=0;j<nnodes;j++)
cout<<j<<"--->"<<parent[j]<<endl;


}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值