最短路径(Floyd法)

最短路径法:

     算法的主要思想是:单独一条边的路径也不一定是最佳路径。 从任意一条单边路径开始。所有两点之间的距离是边的权的和,(如果两点之间没有边相连, 则为无穷大)。 对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短。如果是更新它。 先把所有的结果都计算出来放在数组里面,然后根据需要输出所需要的两点之间的最短路径。用了三个循环来实现

还有一个要Mark一下的是:不如一个数组s[i][j];那可以用这个数组来存放三个数 i,j和s[i][j];

Code:

#include<stdio.h>
#include<stdlib.h>
int a[100][100],cost=99999;
int dian,bian,l,r;//点,边,要求距离的两个点

int main()
{

    int i,j,k;
    printf("输入节点数和路径数\n");
    scanf("%d%d",&dian,&bian);

    //初始化,将对角线全重置为0,其余的全部重置为99999
    for(i=0;i<dian;i++)
        for(j=0;j<dian;j++)
        {
            if(i==j)
                a[i][j]=0;
            a[i][j]=99999;
        }


        //i和j表示节点;a[i][j]表示两点间距离
        printf("输入节点i,j以及i,j之间的距离\n");
        for(k=1;k<=bian;k++)
        {
            scanf("%d%d",&i,&j);
            scanf("%d",&(a[i][j]));
        }

        while(1)
        {
            printf("输入所求最短路径是哪两点\n");
            scanf("%d%d",&l,&r);//输入所求最短路径是哪两点的距离;

            //核心算法程序:注意三个循环的顺序:
            int i,j,k;
            for(k=0;k<dian;k++) //固定一点k,三重循环
                for(i=0;i<dian;i++)
                    for(j=0;j<dian;j++)
                        if(a[i][k]+a[k][j]<a[i][j])
                            a[i][j]=a[i][k]+a[k][j];

            /*
            若i到j的距离大于i到k再到j的距离,
            那么i到j的距离的最小距离很自然变成了i到k再从k到j的距离,
            随着k的变化再一步一步向后动态规划.
            */
            printf("%d \n",a[l][r]);
        }
        return 0;
}


//Input sample:
/*
10 16
0 1
4
0 2
1
1 4
9
1 5
8
2 4
6
2 3
1
2 6
8
3 5
4
3 6
7
6 8
5
4 7
5
4 8
6
5 7
8
5 8
6
7 9
7
8 9
3

Sample:
0 9
15


/*我自己写了一下,在把数组initializate的时候,那个循环条件是到点的数目,只有在输入几个边的距离的时候才是那个M*/

 

 

 

posted @ 2014-12-22 22:58  M_Kepler  阅读(498)  评论(0编辑  收藏  举报