dijkstra最短路 hdu2066

注意,dijkstra  是求最短路的一种方法, 可以算出一个单源点(起点),到图中任意一点的最短距离。


此题用dijkstra算法。

核心算法会记录每条路的距离,然后比较出最短的那条,然后从这条出发,继续和以前记录的比较,一直比较走到想走到的位置。


这一题还有一个技巧,题中给出几个起始点,dijkstra 只是起始点到终点的最短距离,所以按理说应该要调用几次dijkstra函数,不过题目给出了一个好的突破点,可以只调用一次。

题给出,1,2,... ,t 个起始点, 那么我们用map[0][1] = map[0][2] = ... = map[0][t] = 0 即可,则出发点就变为0了,而0到这些起始点的距离其实都为0 ,即没有。


#include<stdio.h>
#include<string.h>
const int INF = 10000000;
const int N = 1000+ 5;
 
int map[N][N],vis[N],lowcost[N]; //起始点到i点最小距离,用lowcost数组记录


void dijkstra(int n)
{
     int pre ;
     memset(vis,0,sizeof(vis));               //标记点数组初始化
     for(int i = 1 ; i < N ; i++ )
     lowcost[i] = INF;                       
     
     vis[0] = 1;   //别忘了这里

     for(int i = 1 ; i <= n ; i++ )
      lowcost[i] = map[0][i];                //给起始点到能连的点路径赋值
      
     for(int i = 1 ; i <= n ; i++ )
     {
             int minn = INF;
             for(int j = 1 ; j <= n ; j++ )
             if(!vis[j]&&lowcost[j]<minn)                      // 记录到j点的最短距离
             {
              minn = lowcost[j] ;
              pre = j;
             }
             vis[pre] = 1;
             for(int k = 1 ; k <=n ; k++ )                             //dijkstra算法核心思想
             if(!vis[k]&&lowcost[k]>lowcost[pre]+map[pre][k])          //到k点的这个路径    和  到pre点的路径+pre和k之间的距离和比较
              lowcost[k] = lowcost[pre]+map[pre][k];
     }
}
     
int main()
{
    int t,s,d,a,b,time;
    int temp;
    int ss[N],ee[N];
    
    while(scanf("%d%d%d",&t,&s,&d)!=EOF)
    {
     temp = 0;
     for(int i = 0 ; i < N ; i++ )
     for(int j = 0 ; j < N ; j++ )
     map[i][j] = INF;                       //初始化每条边无穷大
     
     for(int i = 0 ; i < t ; i++ )
     {
      scanf("%d%d%d",&a,&b,&time);                                // a , b 之间可能有多条路,选短的那条
      map[a][b] = map[a][b]>time?time:map[a][b];
      map[b][a] = map[a][b] ;
      if(a>temp) temp = a;
      if(b>temp) temp = b;                                           //temp 是记录最大的值,即我们最后能走到的那个点
     }                                          
     
     for(int i = 0 ; i < s ; i++ )
     {
       int x ; scanf("%d",&x);
       map[0][x] = 0;                                      //前面说的技巧在这  多个起始点变成一个起始点
     }
     
     dijkstra(temp);
     
     int ans = INF;
     
     for(int i = 0 ; i < d ; i++ )
     {
      int y ; scanf("%d",&y);
      ans = lowcost[y]<ans?lowcost[y]:ans;
     }
     
     printf("%d\n",ans);
    }
    
    return 0;
}
     
     
     
     


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值