图结构练习——最短路径

图结构练习——最短路径

Time Limit: 1000MS Memory limit: 65536K

题目描述

 给定一个带权无向图,求节点1到节点n的最短路径。
 

输入

 输入包含多组数据,格式如下。
第一行包括两个整数n m,代表节点个数和边的个数。(n<=100)
剩下m行每行3个正整数a b c,代表节点a和节点b之间有一条边,权值为c。
 

输出

 每组输出占一行,仅输出从1到n的最短路径权值。(保证最短路径存在)
 

示例输入

3 2
1 2 1
1 3 1
1 0

示例输出

1
0

提示




Floyd算法的基本思想如下:

从任意节点A到任意节点B的最短路径不外乎2种可能,

1是直接从A到B,

2是从A经过若干个节点到B,

所以,我们假设dis(AB)为节点A到节点B的最短路径的距离,对于每一个节点K,我们检查dis(AK) + dis(KB) < dis(AB)是否成立,如果成立,那我们就松弛dis,那就是 dis(AB) = dis(AK) + dis(KB),这样一来,当我们遍历完所有节点K,dis(AB)中记录的便是A到B的最短路径的距离。


  1. #include <stdio.h>   
  2. #include <string.h>   
  3. #include <stdlib.h>   
  4. #define N 102   
  5. #define MAX_N 0x3f3f3f3f   
  6.   
  7. int a[N][N];   
  8.   
  9. int main()   
  10. {   
  11.     int n,m,i,j;   
  12.     int s,b,c;   
  13.     while(~scanf("%d %d",&n,&m))   
  14.     {   
  15.         for(i = 1; i <= n ; i++)            //初始化
  16.         {   
  17.             for(j = 1; j <= n; j++)   
  18.             {   
  19.                 if(i == j)   
  20.                     a[i][j] = 0;   
  21.                 else  
  22.                     a[i][j] = MAX_N;   
  23.             }   
  24.         }   
  25.         for( i = 1 ; i <= m ; i++ )   
  26.         {   
  27.             scanf("%d %d %d",&s,&b,&c);   
  28.             if(a[s][b]>c)                                     //存最小的边
  29.             {   
  30.                 a[s][b] = c;   
  31.                 a[b][s] = c;   
  32.             }   
  33.         }   
  34.         for(int k = 1; k <= n ; k++)                     //Floyd算法的核心
  35.         {   
  36.             for(i = 1; i<= n; i++)   
  37.             {   
  38.                 for(j = 1; j<= n ; j++)   
  39.                 {   
  40.                     if(a[i][j] > a[i][k]+a[k][j])   
  41.                         a[i][j] = a[i][k]+a[k][j];   
  42.                 }   
  43.             }   
  44.         }   
  45.         printf("%d\n",a[1][n]);   
  46.     }   
  47.     return 0;   





   Dijkstra算法


  1. #include <stdio.h>   
  2. #include <string.h>   
  3. #include <stdlib.h>   
  4. #define N 102   
  5. #define MAX_N 0x3f3f3f3f   
  6.   
  7. int a[N][N];   
  8. int book[N],dis[N];   
  9.   
  10. int main()   
  11. {   
  12.     int n,m,i,j;   
  13.     int s,b,c,k,l;   
  14.     while(~scanf("%d %d",&n,&m))   
  15.     {   
  16.         for(i = 1; i <= n ; i++)   
  17.         {   
  18.             for(j = 1; j <= n; j++)   
  19.             {   
  20.                 if(i == j)   
  21.                     a[i][j] = 0;   
  22.                 else  
  23.                     a[i][j] = MAX_N;   
  24.             }   
  25.         }   
  26.         for( i = 1 ; i <= m ; i++ )   
  27.         {   
  28.             scanf("%d %d %d",&s,&b,&c);   
  29.             if(a[s][b] > c)   
  30.             {   
  31.                 a[s][b] = c;   
  32.                 a[b][s] = c;   
  33.             }   
  34.         }   
  35.         for(i = 1; i <= n ; i++)   
  36.         {   
  37.             dis[i] = a[1][i];   
  38.         }   
  39.         for(i = 1; i <= n ; i++)   
  40.         {   
  41.             book[i] = 0;   
  42.         }   
  43.         book[1] = 1;   
  44.         for( i = 1 ; i <= n-1 ; i++ )   
  45.         {   
  46.             int min = MAX_N;   
  47.             for( j = 1 ; j <= n ; j ++ )   
  48.             {   
  49.                 if(book[j] == 0 && dis[j] < min)   
  50.                 {   
  51.                     min =dis[j];   
  52.                     k = j;   
  53.                 }   
  54.             }   
  55.             book[k] = 1;   
  56.             for( l = 1 ; l <= n ; l ++ )   
  57.             {   
  58.                 if( a[k][l] < MAX_N )   
  59.                 {   
  60.                     if(dis[l] > dis[k] + a[k][l])   
  61.                         dis[l] = dis[k] + a[k][l];   
  62.                 }   
  63.             }   
  64.         }   
  65.         printf("%d\n",dis[n]);   
  66.     }   
  67.     return 0;   
  68. }   

代码菜鸟,如有错误,请多包涵!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值