Dijkstra算法-最短路径问题

  • 广度优先
  • 贪心策略
  • 一个数组dist来保存源点到各个顶点的最短距离&&一个保存已经找到了最短路径的顶点的集合
  • 步骤:该集合中只有起点 – 搜寻其相邻所有点与原点距离最近的点 – 把该点加入到集合中 – 更新其他点到这个集合的距离 – 重复以上三个步骤 – 直到该集合包含了所有的元素 (假设不存在负值圈)

  • 邻接矩阵实现
  • 第一个是PAT A1018的一部分,我自己写的
  • 第二个是浙大数据结构慕课里的一个源码
void Dijkstra(int N){
    int collect[MAX]={0};
    for(int i=1;i<=N;i++){
        if(map[0][i]==-1) dest[i]=INFINITY;
        else {
            dest[i]=map[0][i];
            path[i][pathpointer[i]++]=0;//指向往回的路
        }
    }collect[0]=1;
    for(int j=0;j<N;j++){
        int tempdes=INFINITY,temp=0;//没有考虑找不到temp的情况
        for(int i=1;i<=N;i++){ //在集合外的点中找到最短的点temp
            if(collect[i]==0 && dest[i]<tempdes){
                tempdes=dest[i];
                temp=i;
            }
        }collect[temp]=1;//进入集合
        //更新点temp所有相邻点距离该集合的距离
        for(int i=1;i<=N;i++){
            if(map[temp][i]!=-1&&collect[i]==0){
                if(dest[temp]+map[temp][i]<dest[i]) {
                    dest[i] = map[temp][i] + dest[temp];
                    path[i][0] = temp;
                    pathpointer[i] = 1;
                }else if(dest[temp]+map[temp][i]==dest[i]){
                    path[i][pathpointer[i]++]=temp;
                }
            }
        }
    }
    return;
}
/* 邻接矩阵存储 - 有权图的单源最短路算法 */
 
Vertex FindMinDist( MGraph Graph, int dist[], int collected[] )
{ /* 返回未被收录顶点中dist最小者 */
    Vertex MinV, V;
    int MinDist = INFINITY;
 
    for (V=0; V<Graph->Nv; V++) {
        if ( collected[V]==false && dist[V]<MinDist) {
            /* 若V未被收录,且dist[V]更小 */
            MinDist = dist[V]; /* 更新最小距离 */
            MinV = V; /* 更新对应顶点 */
        }
    }
    if (MinDist < INFINITY) /* 若找到最小dist */
        return MinV; /* 返回对应的顶点下标 */
    else return ERROR;  /* 若这样的顶点不存在,返回错误标记 */
}
 
bool Dijkstra( MGraph Graph, int dist[], int path[], Vertex S )
{
    int collected[MaxVertexNum];
    Vertex V, W;
 
    /* 初始化:此处默认邻接矩阵中不存在的边用INFINITY表示 */
    for ( V=0; V<Graph->Nv; V++ ) {
        dist[V] = Graph->G[S][V];
        if ( dist[V]<INFINITY )
            path[V] = S;
        else
            path[V] = -1;
        collected[V] = false;
    }
    /* 先将起点收入集合 */
    dist[S] = 0;
    collected[S] = true;
 
    while (1) {
        /* V = 未被收录顶点中dist最小者 */
        V = FindMinDist( Graph, dist, collected );
        if ( V==ERROR ) /* 若这样的V不存在 */
            break;      /* 算法结束 */
        collected[V] = true;  /* 收录V */
        for( W=0; W<Graph->Nv; W++ ) /* 对图中的每个顶点W */
            /* 若W是V的邻接点并且未被收录 */
            if ( collected[W]==false && Graph->G[V][W]<INFINITY ) {
                if ( Graph->G[V][W]<0 ) /* 若有负边 */
                    return false; /* 不能正确解决,返回错误标记 */
                /* 若收录V使得dist[W]变小 */
                if ( dist[V]+Graph->G[V][W] < dist[W] ) {
                    dist[W] = dist[V]+Graph->G[V][W]; /* 更新dist[W] */
                    path[W] = V; /* 更新S到W的路径 */
                }
            }
    } /* while结束*/
    return true; /* 算法执行完毕,返回正确标记 */
}

再附一个dfs模板

int check(参数)
{
    if(满足条件)
        return 1;
    return 0;
}
 
void dfs(int step)
{
        判断边界
        {
            相应操作
        }
        尝试每一种可能
        {
               满足check条件
               标记
               继续下一步dfs(step+1)
               恢复初始状态(回溯的时候要用到)
        }
}   
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值