(step6.2.2)hdu 1874(畅通工程续——最短路径)

149 篇文章 0 订阅
146 篇文章 1 订阅

题目大意:输入两个整数n,m,分别表示村庄数和道路数。在接下来的m行中,每行有3个整数a,b,c,分别表示起始村庄、结束村庄、以及他们之间的距离。

每个测试数据的最后一行有两个整数start,end。分别表示起点和终点。求从起点到终点的最短距离。


解题思路:最短路径

1)本题一定要注意的是:两点之间可能有多条道路。这是我们要选择最短的那条

           if(map[a][b] > c){
              map[a][b] = map[b][a] = c;//双向道路
           }


如果不注意到这一点的话。很可能会WA出井来。

2)很显然只是最短路径问题,地杰斯特拉算法 和 弗洛伊德算法都可以,10分钟搞定代码 再次在一个细节处理上栽了,以后审题一定要细心,多花点时间琢磨题目中的陷阱,写好代码就很难检查了,1小时都没发现,注意这里两点之间,分清题目是说两点之间的开销预算(一般唯一)还是 之间的道路长度 ,这里两点之间可能存在多条道路,注意取最短的一条(初次筛选)


代码如下:

#include <iostream>
#include <stdio.h>
#include <queue>
#include <string.h>

using namespace std;

#define inf 10000000000000
__int64 map[201][201];
__int64 d[201];
bool hash[201];

__int64 a[201];
__int64 l1,l2,l3,l4,c1,c2,c3,c4;
__int64 n,m;
__int64 start,end;

struct node{
   __int64 adj;
   __int64 weight;
   node* next;
};

struct Heap{
    bool operator<(Heap T)const{
       return T.dis < dis;
    }
  __int64 x;
  __int64 dis;
};

priority_queue<Heap> Q;

__int64 bfs(){
   __int64 i;

   for(i = 0 ; i <= 201 ; ++i){
      hash[i] = 0;
      d[i] = inf;
    }

    Heap min,in;
    while(!Q.empty()){
        Q.pop();
    }

    in.x = start;
    in.dis = 0;
    d[start] = 0;
    Q.push(in);
    while(!Q.empty()){
        min = Q.top();
        Q.pop();

        if(min.x == end){
            return min.dis;
        }

        if(hash[min.x]){
            continue;
        }

        hash[min.x] = true;

        for(i = 0 ; i <= n ; ++i){
            if(d[i] > d[min.x] + map[min.x][i] && !hash[i]){

                in.x = i;
                in.dis = map[min.x][i] + d[min.x];
                d[i] = in.dis;
                Q.push(in);
            }
        }
    }
    return -1;
}

int judge(int dis){

   if(dis > 0 && dis <= l1){
    return c1;
   }else{
      if(dis > l1 && dis <= l2){
        return c2;
      }else{
         if(dis > l2 && dis <= l3){
            return c3;
         }else if(dis >l3 && dis <= l4){
            return c4;
         }else{
            return -1;
         }
      }
   }

}

int main(){
    while(scanf("%I64d%I64d",&n,&m)!=EOF){
        __int64 i,j;
        for(i = 0 ; i <= n ; ++i ){
            for(j = 0 ; j <= n ; ++j){
                map[i][j] = inf;
                map[j][i] = inf;//这个其实不用写,因为它所想表达的意思其实已经包含在上面那一行代码中了

            }
        }

         __int64 a,b,c;
        for(i = 0 ; i < m ; ++i){
           scanf("%I64d%I64d%I64d",&a,&b,&c);
           if(map[a][b] > c){
              map[a][b] = map[b][a] = c;//这个地方一定要注意。两点之间的道路可以有多条,且道路是双向的
           }
        }

        scanf("%I64d%I64d",&start,&end);

        bfs();
        if(d[end] == inf){
            printf("-1\n");
        }else{
            printf("%I64d\n",d[end]);
        }

    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帅气的东哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值