弗洛伊德算法Floyd-最短路径

似乎没什么说的。。。那就不说了????

注意的是,主对角线上面是0

弗洛伊德是插点的

/*弗洛伊德算法,求每对顶点最短路径*/
#include <malloc.h>
#include <iostream>
#include <cstdio>
using namespace std;
#define  MAX_LEN    20//图最大顶点数
#define  INFINITY   255
typedef  bool    path_table[MAX_LEN][MAX_LEN][MAX_LEN];
typedef  int     dist[MAX_LEN][MAX_LEN];
typedef  struct  graph
{
    int vexnum,arcnum;
    int tyust[MAX_LEN][MAX_LEN];
    char vex[MAX_LEN];
}*Graph;

int get_pos(Graph my_map,char c)
{
    for(int i=0;i<my_map->vexnum;i++)
    {
        if(my_map->vex[i]==c)
        {
            return i;
        }
    }
    return -1;
}
void print(Graph my_map)
{
    for(int i=0;i<my_map->vexnum;i++)
    {
        for(int j=0;j<my_map->vexnum;j++)
        {
            printf("%-4d",my_map->tyust[i][j]);
        }
        cout<<endl;
    }
    cout<<endl;
}
Graph  creat_graph()//创建有向图
{
    char in1,in2;
    int vexnum,arcnum;
    int p1,p2,weiget;
    Graph  pit=(Graph)malloc(sizeof(graph));
    cout<<"请输入顶点数和边数"<<endl;
    cin>>vexnum>>arcnum;
    pit->arcnum=arcnum;
    pit->vexnum=vexnum;


    for(int i=0;i<vexnum;i++)
    {
        for(int j=0;j<vexnum;j++)
        {
            if(i==j)pit->tyust[i][j]=0;
            else pit->tyust[i][j]=INFINITY;
        }
    }


    cout<<"请输入顶点:"<<endl;
    for(int i=0;i<vexnum;i++)
        cin>>pit->vex[i];


    for(int i=0;i<arcnum;i++)
    {
        cout<<"请输入边和权重"<<i+1<<endl;
        cin>>in1>>in2>>weiget;
        p1=get_pos(pit,in1);
        p2=get_pos(pit,in2);
        pit->tyust[p1][p2]=weiget;
    }
    print(pit);
    return pit;
}
void Floyd(Graph pit,path_table p,dist d)
{
    //初始化
    for(int i=0;i<pit->vexnum;i++)
    {
        for(int j=0;j<pit->vexnum;j++)
        {
            d[i][j]=pit->tyust[i][j];
            for(int k=0;k<pit->vexnum;k++)
                p[i][j][k]=false;
            if(d[i][j]<INFINITY)
                p[i][j][i]=p[i][j][j]=true;
        }
    }
    ////////////////////////////////////////
    for(int i=0;i<pit->vexnum;i++)
    {
        for(int j=0;j<pit->vexnum;j++)
        {
            for(int k=0;k<pit->vexnum;k++)
            {
                if(i!=j&&i!=k&&j!=k&&d[j][i]<INFINITY&&d[i][k]<INFINITY&&d[j][i]+d[i][k]<d[j][k])
                {
                    //插入i
                    //更新最小距离
                    d[j][k]=d[j][i]+d[i][k];
                    for(int temp=0;temp<pit->vexnum;temp++)
                    p[j][k][temp]=p[j][i][temp]||p[i][k][temp];//一个为真即是真
                }
            }
        }
    }
}


void make_path(Graph g,bool *p,int i,int j)//路径寻找
{
    int start=i;//start等于开始点也就是0
    int my_min,temp;
    while(start!=j)
    {
        my_min=INFINITY;
        for(int k=0;k<g->vexnum;k++)//寻找最小的,这是符合我们的先前记录的顺序的
        {
            if(g->tyust[start][k]<my_min&&p[k])
            {
                my_min=g->tyust[start][k];
                temp=k;
            }
        }
        if(my_min==INFINITY)break;

        printf("%c",g->vex[temp]);
        if(temp!=j)//不是终点
        printf("->");
        p[temp]=false;//标志
        start=temp;
    }
    cout<<endl;
}
int main()
{
    bool *path;
    path_table p;//三维数组
    dist d;//二维数组
    Graph pit=creat_graph();
    Floyd(pit,p,d);
    path=(bool *)malloc(MAX_LEN*sizeof(bool));
    for(int i=0;i<pit->vexnum;i++)
    {
        for(int j=0;j<pit->vexnum;j++)
        {
            if(i!=j)//不是本身
            {
                cout<<pit->vex[i]<<"->"<<pit->vex[j]<<"  ";
                for(int k=0;k<pit->vexnum;k++)
                {
                    cout<<p[i][j][k]<<"  ";
                    path[k]=p[i][j][k];
                }
                cout<<endl<<"最短路径:"<<d[i][j]<<"  ";
                make_path(pit,path,i,j);
            }
        }
    }
    return 0;
}

弗洛伊德算法Floyd-最短路径