最短路径(Dijkstra,Floyd)

最短路径

两顶点间经过的边上权值之和最少的路径。
源点:第一个顶点
终点:最后一个顶点

Dijkstra 算法 O(n^2)

#define MAXX 65535
int a[10][10];//邻接矩阵,没有边就设为MAXX, i,j相等为0
int p[10];//最短路径下标,记录前一点的下标
int d[10];//到各点最短路径的权值和
void Dijkstra(int q)//q为出发点
{
   int v,w,k,minn;
   int f[10];//f[w]=1  表示w点被连
   for(v=0;v<9;v++)
   {
       f[v]=0;
       d[v]=a[q][v];
       p[v]=0;
   }
   d[q]=0;
   f[q]=1;
   for(v=1;v<9;v++)
   {
       minn=MAXX;
       for(w=0;w<9;w++)
       {
           if(!f[w]&&d[w]<minn)//找权值最小的点
           {
               k=w;
               minn=d[w];
           }
       }
       f[k]=1;
       for(w=0;w<9;w++)
       {
           if(!f[w]&&(minn+a[k][w])<d[w])//改变d,p数组
           {
               d[w]=minn+a[k][w];
               p[w]=k;
           }
       }
       for(int i=0;i<9;i++)
       cout<<p[i]<<" ";
       cout<<endl;
   }
}

单源最短路径
最后d数组的值表示源点到各点的最短路径数
p数组表示各点的前一点

Floyd O(n^3)

#define MAXX 65535
int a[10][10],d[10][10],p[10][10];
void Floyd(int a[10][10])
{
    int v,k,w;
    for(v=0; v<9; v++)
    {
        for(w=0; w<9; w++)
        {
            d[v][w]=a[v][w];
            //cout<<d[v][w]<<" ";
            p[v][w]=w;
        }
    }
    
    for(k=0; k<9; k++)
        for(v=0; v<9; v++)
            for(w=0; w<9; w++)
            {
                if(d[v][w]>(d[v][k]+d[k][w]))
                {
                    d[v][w]=d[v][k]+d[k][w];
                    p[v][w]=p[v][k];//经过下标为k的顶点
                }
            }
            
    for(v=0;v<9;v++)
    {
        for(w=v+1;w<9;w++)
        {
            printf("v%d->v%d wight: %d",v,w,d[v][w]);
            k=p[v][w];
            printf("path: %d",v);
            while(k!=w)
            {
                printf("->%d",k);
                k=p[k][w];
            }
            printf("->%d\n",w);
        }
        printf("\n");
    }
}

判断经过k点是否会减少路径长度是关键
代码简单,有点难理解,时间复杂度高

发布了7 篇原创文章 · 获赞 1 · 访问量 1437

猜你喜欢

转载自blog.csdn.net/weixin_45833157/article/details/104675508