题目大意:输入两个整数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]);
}
}
}