POJ - 2387 Til the Cows Come Home (kuangbin - 最短路练习)

题目描述(已转换成中文)

  cht很热爱学习,他打算偷偷跑回学校学习,为了多学习他希望可以找最快的路线回到学校。
  北京市里有N个(2 <= N <= 1000)个地铁站,编号分别为1…N。cht家在1号地铁站旁边,清华大学旁边是N号地铁站。地铁站之间共有M (1 <= M <= 2000)条双向路径。
  cht现在在1号地铁站,他希望知道到学校最短要多长时间。可以保证cht能到达学校。忽略cht在换乘地铁时需要的等待时间

输入格式

  第一行:两个整数:M和N
  接下来M行:每一行有A B C三个整数。代表A站到B站或者B站到A站需要C分钟,C的范围为1到100。

输出格式

  一个整数,表示cht回到学校的最少时间。

输入输出样例
输入

5 5
1 2 20
2 3 30
3 4 20
4 5 20
1 5 100

输出

90

题目链接

分析:

  

这道题需要注意的地方:

  

代码如下:

一:

  Dijkstra算法的朴素实现:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <queue>
using namespace std;
typedef long long LL;
const int N = 1005;
int n, m, g[N][N], dist[N], st[N];	//g数组是记录从某点到某点的权值,dist数组表示任意点到点1的最短距离,st数组是标记已求出最短路径的顶点
int read(){
    int x, f = 1;
    char ch;
    while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
    x = ch - '0';
    while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;
    return x * f;
}
int dijkstra(){
    int i, j, t;
    memset(dist, 0x3f, sizeof(dist)); //把所有点到起点最短距离初始化为正无穷
    dist[1] = 0;	//起点到起点的最短距离为0
    for(i = 1; i <= n; i++){	//每轮循环得到一个确定最短路径的顶点
        t = -1;	//t是个临时变量,为了确定某个点到起点的最短距离,并且把其放入已求出最短路径的顶点的集合里面
        for(j = 1; j <= n; j++){
            if(!st[j] && (t == -1 || dist[t] > dist[j])) t = j;
        }
        st[t] = 1;	//标记t点已经被放入已求出最短路径的顶点的集合里面
        for(j = 1; j <= n; j++){
            dist[j] = min(dist[j], dist[t] + g[t][j]); //更新未确定最短路径的顶点 目前已得到的最短路径
        }
    }
    if(dist[n] == 0x3f3f3f3f) return -1;	//此点跟起点不是连通的
    return dist[n];	//返回点n到起点的最短路径
}
int main(){
    int a, b, c;
    m = read();
    n = read();
    memset(g, 0x3f, sizeof(g));	//把各个点之间的距离都初始化为正无穷
    while(m--){
        a = read();
        b = read();
        c = read();
        g[a][b] = g[b][a] = min(g[a][b], c);	//因为这是无向图,所以从a到b和从b到a的距离相同,两点的距离可能会被读入不同的数据,取那个最短的距离,便于后续求最短路径
    }
    printf("%d\n", dijkstra());
    return 0;
}
二:

  Dijkstra算法利用优先队列实现:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <map>
#include <queue>
using namespace std;
typedef long long LL;
int read(){
	int x, f = 1;
	char ch;
	while(ch = getchar(), ch < '0' || ch > '9') if(ch == '-') f = -1;
	x = ch - '0';
	while(ch = getchar(), ch >= '0' && ch <= '9') x = x * 10 + ch - 48;
	return x * f;
}
typedef pair<int, int> PII;
const int N = 4005;
int n, m, h[N], w[N], e[N], ne[N], idx, dist[N], st[N];
void add(int a, int b, int c){
	e[idx] = b;
	w[idx] = c;
	ne[idx] = h[a];
	h[a] = idx++;
}
int dijkstra(){
	int ver, distance, i, j;
	memset(dist, 0x3f, sizeof(dist));
	dist[1] = 0;
	priority_queue <PII, vector<PII>, greater<PII> > heap;
	heap.push({0, 1});
	while(heap.size()){
		PII t = heap.top();
		heap.pop();
		ver = t.second;
		if(st[ver]) continue;
		st[ver] = 1;
		for(i = h[ver]; i != -1; i = ne[i]){
			j = e[i];
			if(dist[j] > dist[ver] + w[i]){
				dist[j] = dist[ver] + w[i];
				heap.push({dist[j], j});
			}
		}
	}
	if(dist[n] == 0x3f3f3f3f) return -1;
	return dist[n]; 
}
int main(){
	int a, b, c; 
	m = read();
	n = read();
	memset(h, -1, sizeof(h));
	while(m--){
		a = read();
		b = read();
		c = read();
		add(a, b, c);
		add(b, a, c);
	}
	printf("%d\n", dijkstra());
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值