您的位置:首页 > 其它

[hihoCoder] #1093 : 最短路径·三:SPFA算法

2015-04-08 15:57 337 查看
时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

万圣节的晚上,小Hi和小Ho在吃过晚饭之后,来到了一个巨大的鬼屋!

鬼屋中一共有N个地点,分别编号为1..N,这N个地点之间互相有一些道路连通,两个地点之间可能有多条道路连通,但是并不存在一条两端都是同一个地点的道路。

不过这个鬼屋虽然很大,但是其中的道路并不算多,所以小Hi还是希望能够知道从入口到出口的最短距离是多少?

提示:Super Programming Festival Algorithm。

输入

每个测试点(输入文件)有且仅有一组测试数据。

在一组测试数据中:

第1行为4个整数N、M、S、T,分别表示鬼屋中地点的个数和道路的条数,入口(也是一个地点)的编号,出口(同样也是一个地点)的编号。

接下来的M行,每行描述一条道路:其中的第i行为三个整数u_i, v_i, length_i,表明在编号为u_i的地点和编号为v_i的地点之间有一条长度为length_i的道路。

对于100%的数据,满足N<=10^5,M<=10^6, 1 <= length_i <= 10^3, 1 <= S, T <= N, 且S不等于T。

对于100%的数据,满足小Hi和小Ho总是有办法从入口通过地图上标注出来的道路到达出口。

输出

对于每组测试数据,输出一个整数Ans,表示那么小Hi和小Ho为了走出鬼屋至少要走的路程。

样例输入
5 10 3 5
1 2 997
2 3 505
3 4 118
4 5 54
3 5 480
3 4 796
5 2 794
2 5 146
5 4 604
2 5 63

样例输出
172


#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <climits>
using namespace std;

const int INF = 1e9;

struct node {
int idx;
int len;
node(int _idx = 0, int _len = 0) : idx(_idx), len(_len){}
};

int N, M, S, T;
vector<vector<node>> graph;
vector<int> dist;

void solve() {
vector<int> visit(N+1, false);
//priority_queue<int, vector<int>, greater<int>> heap;
queue<int> heap;
dist[S] = 0;
heap.push(S);
visit[S] = true;
while (!heap.empty()) {
//int u = heap.top();
int u = heap.front();
heap.pop();
visit[u] = false;
for (int i = 0; i < graph[u].size(); ++i) {
int v = graph[u][i].idx;
if (dist[v] > dist[u] + graph[u][i].len) {
dist[v] = dist[u] + graph[u][i].len;
if (!visit[v]) {
heap.push(v);
visit[v] = true;
}
}
}
}
cout << dist[T] << endl;
}

int main() {
while (cin >> N >> M >> S >> T) {
graph.assign(N+1, vector<node>(0));
dist.assign(N+1, INF);
int u, v, len;
for (int i = 1; i <= M; ++i) {
cin >> u >> v >> len;
graph[u].push_back(node(v, len));
graph[v].push_back(node(u, len));
}
solve();
}
return 0;
}


堆优化的Dijkstra算法。总体来说还是SPFA算法更好写一点。不过Dijsktra算法可以提前输出,只到轮到点T,直接输出即可。

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;

const int INF = 1e9;

struct edge {
int idx;
int dist;
edge(int _idx, int _dist) : idx(_idx), dist(_dist) {}
};

struct cmp {
bool operator () (const edge &a, const edge &b) { return a.dist > b.dist; }
};

int N, M, S, T;
vector<vector<edge>> graph;

void solve() {
priority_queue<edge, vector<edge>, cmp> heap;
vector<int> dist(N + 1, INF);
vector<bool> visit(N + 1, false);
dist[S] = 0;
visit[S] = true;
for (int i = 0; i < graph[S].size(); ++i) {
auto v = graph[S][i];
dist[v.idx] = min(dist[v.idx], v.dist);
heap.push(edge(v.idx, dist[v.idx]));
}
while (!heap.empty()) {
auto u = heap.top();
heap.pop();
if (u.idx == T) {
cout << u.dist << endl;
return;
}
if (visit[u.idx]) continue;
visit[u.idx] = true;
for (int i = 0; i < graph[u.idx].size(); ++i) {
auto v = graph[u.idx][i];
if (!visit[v.idx] && dist[v.idx] > dist[u.idx] + v.dist) {
dist[v.idx] = dist[u.idx] + v.dist;
heap.push(edge(v.idx, dist[v.idx]));
}
}
}
cout << "-1" << endl;
}

int main() {
while (cin >> N >> M >> S >> T) {
int u, v, len;
graph.resize(N + 1);
for (int i = 0; i < M; ++i) {
cin >> u >> v >> len;
graph[u].push_back(edge(v, len));
graph[v].push_back(edge(u, len));
}
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: