单源最短路径

 

Dijkstra算法:

        Dijkstra算法可以将所有顶点分成三个集合,源点集合{A},已经计算出最短路径的顶点集合U,和未计算出最短路径的顶点集合.

1.初始状态时候,集合U为空,集合T等于V-{A},并初始化设置集合T中顶点的当前最短路径.

2.选取集合T中路径长度最短的元素加入到集合U.

3.更新集合T中的元素对应的当前最短距离.此时集合T中的元素对应的路径,总是源点A经过集合U中的某些顶点(或者没有经过),到达集合T中的顶点时的最短路径.

4.如果T不为空,回到2,否则结束.

 

注意:

1.在集合T中路径最短的点,该点记录的路径就是A到达该点的最短路径.此时把该点从集合T中移到集合U.这就是为什么第3步中,要从集合T选取的路径最短的节点的原因.

2.为什么集合T中路径最短的点,该点记录的路径就是A到达该点的最短路径?

反证法:把集合T中路径最短的点记作B,假设B点记录的路径不是AB的最短路径,那么必定有一条路径比此时的路径小,如果该条路径直接由A到达B,那么此后对该顶点所记录的距离就不会进行更新.如果顶点A途经某个节点到达B.我们把该节点记为C,易知节点C必定不在集合U(如果在集合U,那么在第3步更新集合T的时候,就不是使得B点记录的路径变大为当前记录的路径.),而且不在集合T(因为若在集合T,顶点C记录的距离一定比B的小,就会优先选择顶点C,而不会选择顶点B),所以顶点C不在T,不在U,即不存在顶点c.而且B所记录的路径就是最短路径.


 

 

在编程过程中出现的错误:

循环忘了后移导致死循环.

#include<iostream>
#include<deque>
#include<queue>
 
usingnamespace std;
#defineVexNum 5
#defineVEXMAX 100000
typedefchar VextexType;
typedefint  EdgeType;
 
 
structEdgeNode;
structEdgeNode {
    VextexType HeadName;
    VextexType TailName;
    EdgeType  weight;
    EdgeNode  *VexOut;
    EdgeNode  *VexIn;
    bool operator < (const EdgeNode&node)const {
        return weight > node.weight;
    }
};
 
structvexWeight{
    char name;
    int pathWeight;
    char path[VexNum+1];
};
 
typedefstruct
{
    VextexType name;
    EdgeNode  *VexOutlink;
    EdgeNode  *VexInlink;
}VexNode;
 
VexNodeadjList[VexNum];
boolvisit[VexNum];
intfather[VexNum];
intrank_set[VexNum];
 
 
 
voidcreatGraph()
{
 
    VextexType vextemp;
    EdgeType  edgetemp;
    char a[]={'A','B','C','D','E'};
 
    int b[] = { 0, 1, 0, 1, 0,
                0, 0, 6, 2, 0,
                0, 0, 0, 0, 2,
                0 ,1, 0, 0, 1,
                0, 0, 1, 0, 0};
    //input n vextex
    for ( int i=0; i<VexNum ; ++i ){
       // cin>>vextemp;
        vextemp = a[i];
        adjList[i].name       = vextemp;
        adjList[i].VexOutlink = NULL;
        adjList[i].VexInlink  = NULL;
    }
    for ( int i=0; i<VexNum*VexNum; ++i ){
        //cin>>edgetemp;
        edgetemp = b[i];
        if ( edgetemp==0 ){
            continue;
        }
 
        EdgeNode *pEdge = new EdgeNode;
        pEdge->HeadName =adjList[i/VexNum].name;
        pEdge->TailName =adjList[i%VexNum].name;
        pEdge->weight   = edgetemp;
 
        pEdge->VexOut   = adjList[i/VexNum].VexOutlink;
        if ( pEdge->VexOut ){
            while ( pEdge->VexOut->VexOut){
                pEdge->VexOut=pEdge->VexOut->VexOut;
            }
            pEdge->VexOut->VexOut =pEdge;
            pEdge->VexOut=NULL;
        } else {
            adjList[i/VexNum].VexOutlink =pEdge;
            pEdge->VexOut = NULL;
        }
    }
    for ( int i=0 ;i<VexNum ;++i ){
        EdgeNode **pInLink =&adjList[i].VexInlink;
        for ( int j=0; j<VexNum; ++j ){
            if ( i==j ){
                continue;
            }
            EdgeNode *p =adjList[j].VexOutlink;
            while ( p ){
                if ( p->TailName !=adjList[i].name ){
                    p = p->VexOut;
                    continue;
                }
                *pInLink = p;
                pInLink = &p->VexIn;
                p = p->VexOut;
            }
        }
        *pInLink = NULL;
    }
}
 
voiddestroyGrape()
{
    for ( int i=0; i<VexNum ;++i ){
        EdgeNode *p = adjList[i].VexOutlink;
        EdgeNode *q;
        while ( p ){
            q = p;
            p = p->VexOut;
            delete q;
        }
    }
 
 
}
 
voidprintGrape()
{
    for ( int i=0; i<VexNum; ++i ){
       cout<<adjList[i].name<<"-->";
        EdgeNode *p = adjList[i].VexOutlink;
        while ( p ){
           cout<<"("<<p->HeadName<<","<<p->TailName<<","<<p->weight<<")";
            p = p->VexOut;
        }
        cout<<endl;
        p = adjList[i].VexInlink;
       cout<<adjList[i].name<<"-->";
        while ( p ){
           cout<<"("<<p->HeadName<<","<<p->TailName<<","<<p->weight<<")";
            p = p->VexIn;
        }
        cout<<endl;
 
    }
}
 
voidDijsktra()
{
    vexWeight vexwe[VexNum];
    EdgeNode *p = NULL;
    vexWeight vexTemp ;
  
    char bitMap = 0;
 
    for ( int i=0; i<VexNum; ++i ){
        vexwe[i].pathWeight = VEXMAX;
        vexwe[i].path[0]='A';
        vexwe[i].name = 'A'+i;
        for ( int j=1; j<VexNum+1; ++j ){
            vexwe[i].path[j]=0;
        }
    }
   
    p = adjList[0].VexOutlink;
    while ( p ){
       vexwe[p->TailName-'A'].pathWeight=p->weight;
        vexwe[p->TailName-'A'].path[1] =p->TailName;
        p = p->VexOut;
    }
 
    for ( int i=1; i<VexNum; ++i ){
        int currentWeight = VEXMAX;
        int vexPos = 0;
        for ( int k=1; k<VexNum; ++k ){
            if ( ( bitMap & 1<<k) 
                || vexwe[k].pathWeight >=currentWeight  ){
                continue;
            }
            currentWeight =vexwe[k].pathWeight;
            vexPos = k;
        }
        if ( vexPos == 0 ||vexwe[vexPos].pathWeight == VEXMAX ){
           cout<<"error"<<endl;
            return ;
        }
 
        bitMap |= 1<<vexPos;
        p = adjList[vexPos].VexOutlink;
        while ( p ){
            int vexPosExtern =p->TailName-'A';
            int externWeight =  currentWeight + p->weight;
            if ( ( bitMap &1<<vexPosExtern )
                || externWeight >=vexwe[vexPosExtern].pathWeight){
                p = p->VexOut;
                continue;
            }
            vexwe[vexPosExtern].pathWeight=  externWeight;
 
            int j=0;
            while ( vexwe[vexPos].path[j] ){
                vexwe[vexPosExtern].path[j] =vexwe[vexPos].path[j];
                ++j;
            }
          
            vexwe[vexPosExtern].path[j] =vexwe[vexPosExtern].name;
            p = p->VexOut;
        }
 
    }
 
    for ( int i =1; i<VexNum; ++i ){
        cout<<vexwe[i].path<<endl;
    }
 
}
 
int main()
{
    creatGraph();
    printGrape();
    Dijsktra();
    destroyGrape();
}


input数据:


结果:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值