Dijkstra and Floyd

Dijkstra算法使用了广度优先搜索解决赋权有向图或者无向图的单源最短路径问题,算法最终得到一个最短路径树。使用了贪心策略,创建数组A,保存原点到其他顶点的距离(不能直接到达的路径长度为无穷大),创建数组B,以原点为起点,保存已经找到的最短路径的顶点。然后从A数组选择最小值作为原点到该值对应顶点的最短路径,并且把该点加入到数组B中。接着查看该点是否可以到达其他顶点,并比较该点到其他顶点的路径长度是否比原点直接到达短,如果是,则替换这些顶点在数组A中的值。重读以上过程,直到数组B包含所有顶点。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

#define SIZE 110  
#define INF 1000000

int map[SIZE][SIZE];  //邻接矩阵存储 
int len[SIZE];  	//d[i]表示源点到i这个点的距离 
int visit[SIZE];  //节点是否被访问 
int n, m;

int dijkstra(int from, int to) {	//从源点到目标点 

    int i;

    for (i = 1; i <= n; i++) {	//初始化 
        visit[i] = 0;	//一开始每个点都没被访问 
        len[i] = map[from][i];	//先假设源点到其他点的距离 
    }

    int j;
    for (i = 1; i < n; ++i) {	//对除源点的每一个点进行最短计算 
        int min = INF;  //记录最小len[i] 
        int pos;  

        for (j = 1; j <= n; ++j) {
            if (!visit[j] && min > len[j]) {
                pos = j;
                min = len[j];
            }
        }
        visit[pos] = 1;

        for (j = 1; j <= n; ++j) {
            if (!visit[j] && (len[j] > (len[pos] + map[pos][j]))) { //如果j节点没有被访问过&&j节点到源节点的最短路径>pos节点到源节点的最短路径+pos节点到j节点的路径  
                len[j] = len[pos] + map[pos][j];	//更新j节点到源节点的最短路径	
            }
        }
    }

    return len[to];
}


int main() {

    int i, j;

      scanf("%d%d",&n,&m);	//输入数据
    

    for (i = 1; i <= n; ++i) {	//设一开始每个点都不可达 
        for (j = 1; j <= n; ++j) {
            map[i][j] = INF;
        }
    }

    	int a,b,c;	//输入数据
        for(i = 1 ; i <= m ; ++i){
            scanf("%d%d%d",&a,&b,&c);
            map[a][b] = map[b][a] = c;
        }  

    
    int temp = INF;
    for (i = 1; i <= n; ++i) {
        for (j = 1; j <= n; ++j) {
            if (map[i][j] == temp)
                map[i][j] = map[j][i];
        }
    }

    int ans = dijkstra(1, 5);

    printf("%d", ans);

    return 0;
}

.关于Floyd算法,从起点出发到终点,中间经过的任一节点满足以下条件,如果该点位于起点到终点的最短路径上,那么起点到终点的最短路径就等于起点到该点的距离加上该点到终点的距离。如果某点不在最短路径上,那么起点到终点的最短距离就小于起点到该点加上该点到终点的距离。

1 2 3 4
1 \ 2 6 4
2 \ \ 3
3 7 \ \ 1
4 5 \ 12
核心伪代码`

Int D[][]={}//输入矩阵
Int S[][];   //
n=4;
For(i 1 to n){// 初始化矩阵S
.......
}

For(k 1 to n){
For(i 1 to n){
For(j 1 to n){
If(D[i][j]+D[k][j]<D[i][j]){
D[i][j]+D[i][k]=D[k][j];
S[i][j]=S[i][k];
}}}}

For(){   //输出距离矩阵
For(){
......
}
}
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
    int e[10][10], k, i, j, n, m, t1, t2, t3;
    int inf = 99999999; 
    //读入n和m,n表示顶点个数,m表示边的条数
    scanf("%d %d", &n, &m);
    //初始化
    for (i = 1; i <= n; i++)
        for (j = 1; j <= n; j++)
            if (i == j) e[i][j] = 0;
            else e[i][j] = inf;
   
    for (i = 1; i <= m; i++)
    {
        scanf("%d %d %d", &t1, &t2, &t3);
        e[t1][t2] = t3;
    }
    //核心
    for (k = 1; k <= n; k++)
        for (i = 1; i <= n; i++)
            for (j = 1; j <= n; j++)
                if (e[i][j] > e[i][k] + e[k][j])
                    e[i][j] = e[i][k] + e[k][j];
 
    for (i = 1; i <= n; i++)
    {
        for (j = 1; j <= n; j++)
        {
            printf("%10d", e[i][j]);
        }
        printf("\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值