ACM—三种最短路算法

版权声明:沃斯里德小浩浩啊 https://blog.csdn.net/Healer66/article/details/82054178

1.炒鸡简单的floyd(弗洛伊德)算法

求图中任意两点间的最短路径,三层循环,第一层枚举中间点,第二层枚举起点,第三层枚举终点。从小到大更新,发现更短路则立即更新。

代码简单换来的是O(n^3)复杂度。对于数据量大的题并不合适。

void floyd(int dis[][], int n)
{
    for(int k = 0; k < n; ++k) 
        for(int i = 0; i < n; ++i) 
            for(int j = 0; j < n; ++j) 
                g[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
}
//dis数组未知两点间的距离置为INF(就是一个炒鸡大的数)

 2.有点意思的Dijkstrad(迪杰斯特拉)

Dijkstrad算法求的是图中一个点到图中所有点的最短路。简单来说,将所有的点分成两个集合,S和D,S初始时只包含 起点,D中包含除起点外的所有点。然后不断重复以下操作:从D中找到距离起点最近的点k,将其加入到S中,再利用k 更新D中剩余点到起点的距离(用最近来更新最终得到的才是最近(短)路)。直到D为空集,结束操作。

  简单版Dijkstrad代码:


void Dijkstra(int start)//最短路dijkstra算法
{
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++)
        dis[i]=(i==start?0:inf);//初始化,起点dis[start]=0, 其它均为最大值inf
    for(int i=1;i<=n;i++)
    {
            int x,mini=inf;//x为集合D中dis[i]存在最小值的那个顶点编号
            for(int y=1;y<=n;y++)
            if(!vis[y]&&dis[y]<=mini)
            {
                mini=d[y];
                x=y;//两句可以合写为mini=d[x=y];
            }
               vis[x]=1;//找到的顶点加入集合S;
        for(int y=1;y<=n;y++)
            dis[y]=min(dis[y],dis[x]+w[x][y]);  //更新D中点到起点的距离
    }
}

    优先队列优化的Dijkstra算法

        简单来说,就是缩短了查找集合D中距离起点最近的点时间。

     

const int INF = 0x3f3f3f3f;
const int maxn = 1000010;
struct qnode
{
    int v,c;
    qnode(int vv = 0,int c c= 0):v(vv),c(cc){}
    bool operator < (const qnode&r)const
    {
      return c > r.c;
    }
};
struct Edge
{
    int v, cost;
    Edge(int vv = 0,int ccost=0):v(vv),cost(ccost){}
};
vector<Edge> E[maxn];
bool vis[maxn];
int dis[maxn];
void Dijkstra(int n,int start)
{
    memset(vis,0,sizeof vis);
    for(int i=0;i<n;i++)
    {
        dis[i]=INF;
    }
    priority_queue<qnode> que;
    while(!que.empty())
        que.pop();
    dis[start]=0;
    que.push(qnode(start,0));
    qnode tmp;
    while(!que.empty())
    {
        tmp = que.top();
        que.pop();
        int u = tmp.v;
        if(vis[u])
         continue;
        vis[u] = true;
        for(int i = 0;i < E[u].size();i++)
        {
            int v=E[tmp.v][i].v;
            int cost = E[u][i].cost;
            if(!vis[v] && dis[v] > dis[u] + cost)
            {
                dis[v] = dis[u]+cost;
                que.push(qnode(v,dis[v]));
            }
        }
    }
}
void Addedge(int u,int v,int w)
{
    E[u].push_back(Edge(v,w));
}

   3.帅哥最爱用的SPFA(Shortest Path Faster Algorithm)算法

      关于这个算法不想多说,这个博客写的炒鸡棒:

        https://blog.csdn.net/maxichu/article/details/45309463

void SPFA(int s)
{
    int i,now;
    for( i = 1;i <= n; i++ )
    {
        dist[i] = Max;
        vist[i] = 0;
    }
    dist[s] = 0;
    queue<int>q;
    q.push(s);
    vist[s] = 1;
    while (!q.empty())
    {
        now = q.front();
        q.pop();
        vist[now] = 0;
        for( i = 1;i < =n; i++)
        {
            if (dist[i] > dist[now] + Map[now][i])
            {
                dist[i] = dist[now] + Map[now][i];
                if (vist[i] == 0)
                {
                    q.push(i);
                    vist[i] = 1;
                }
            }
        }
    }

}

                

              

 

猜你喜欢

转载自blog.csdn.net/Healer66/article/details/82054178