最短路算法模版

最短路 

dijkstra算法(main函数别忘了初始化)

void dis()
{
    int i, j, min , v;
    int dist[N];
    bool visit[N];

    for(i=1; i<=n; i++)
    {
        visit[i]=0;
        dist[i]=map[1][i];//从1为起点开始初始化1到各点的距离
    }

    for(i=1; i<=n; i++)
    {
        min = inf;
        for(j=1; j<=n; j++)
        {
            if(!visit[j]&&min>dist[j])//找到未被访问的最近的点

            {
                min=dist[j];
                v=j;
            }
        }
        visit[v]=1;

        for(j=1; j<=n; j++)
        {
            if(!visit[j]&&dist[j]>dist[v] + map[v][j])//松弛
                dist[j] = dist[v] + map[v][j];
        }

    }

    printf("%d\n", dist[n]);
}
Floyd算法(时间复杂度为O(n^3))

void Floyd()

{

for(int k=1;k<=n;k++)
{
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            map[i][j]=min(map[i][j],map[i][k]+map[k][j]);//可以求出任意两点的最短路;
        }
    }
}

}

Bellmanford 算法

适用条件&范围:

单源最短路径(从源点s到其它所有顶点v);

有向图&无向图(无向图可以看作(u,v),(v,u)同属于边集E的有向图);

边权可正可负(如有负权回路输出错误提示);

差分约束系统;

Bellman-Ford算法的流程如下: 给定图G(V, E)(其中VE分别为图G的顶点集与边集),源点s数组Distant[i]记录从源点s到顶点i的路径长度,初始化数组Distant[n], Distant[s]0

以下操作循环执行至多n-1次,n为顶点数: 对于每一条边e(u, v),如果Distant[u] + w(u, v) < Distant[v],则另Distant[v] = Distant[u]+w(u, v)w(u, v)为边e(u,v)的权值; 若上述操作没有对Distant进行更新,说明最短路径已经查找完毕,或者部分点不可达,跳出循环。否则执行下次循环;

为了检测图中是否存在负环路,即权值之和小于0的环路。对于每一条边e(u, v),如果存在Distant[u] + w(u, v) < Distant[v]的边,则图中存在负环路,即是说改图无法求出单源最短路径。否则数组Distant[n]中记录的就是源点s到各顶点的最短路径长度。

可知,Bellman-Ford算法寻找单源最短路径的时间复杂度为O(V*E).

BellmanFord算法可以大致分为三个部分 第一,初始化所有点。每一个点保存一个值,表示从原点到达这个点的距离,将原点的值设为0,其它的点的值设为无穷大(表示不可达)。 第二,进行循环,循环下标为从1n1n等于图中点的个数)。在循环内部,遍历所有的边,进行松弛计算。 第三,遍历途中所有的边(edgeuv)),判断是否存在这样情况: dv) > d (u) + w(u,v) 则返回false,表示途中存在从源点可达的权为负的回路。


bool Bellmanford(int n, int k)
{
    int i, j;
    bool flag;

    for(i=1; i<n; i++)
    {
        flag =false;
        for(j=0; j<k; j++)
        {
            if(dist[G[j].v]>dist[G[j].u]+G[j].w)
            {
                dist[G[j].v] = dist[G[j].u]+G[j].w;
   
            }
        }

    }

    for(i=0; i<k; i++)
    {
        if(dist[G[i].v]>dist[G[i].u]+G[i].w)
            return true;
    }
    return false;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值