POJ 2387.Til the Cows Come Home

题目链接:http://poj.org/problem?id=2387
这是一个单源最短路径的裸题,写篇博客复习下Dijkstra算法以及邻接表和邻接矩阵。
邻接矩阵写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <algorithm>
#include <cstring>

using namespace std;

const int maxn = 1010;
const int inf = 0x3f3f3f3f;
int mp[maxn][maxn];
bool vis[maxn];
int ans[maxn];
int T, N;
void dijkstra(int st){
memset(vis, false, sizeof vis);
ans[1] = 0;
for (int i = 1; i <= N; ++i){
int tmp = inf;
for (int j = 1; j <= N; ++j){
if (!vis[j] and tmp > ans[j]){
tmp = ans[st = j];
}
}
vis[st] = true;
for (int j = 1; j <= N; ++j){
ans[j] = min(ans[j], ans[st] + mp[st][j]);
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> T >> N){
memset(mp, 0x3f, sizeof mp);
memset(ans, 0x3f, sizeof ans);
int a,b,dis;
for (int i = 0; i < T; ++i){
cin >> a >> b >> dis;
if (mp[a][b] > dis){
mp[a][b] = mp[b][a] = dis;
}
}
dijkstra(1);
cout << ans[N] << endl;
}
return 0;
}

用邻接矩阵的时候对于$N$比较大的情况,遍历矩阵的方式导致消耗的时间激增,如果边的数量比较少,但是$N$比较大,即稀疏图的时候,采用邻接表可以节约大量的遍历时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <queue>

using namespace std;

const int inf = 0x3f3f3f3f;
const int maxn = 1010;
const int maxm = 4020;
int head[maxn];
int ans[maxn];
int u[maxm];
int v[maxm];
int cnt[maxm];
int pre[maxm];
int edge_cnt;
int N, T;
bool vis[maxn];
priority_queue<pair<int, int>,vector<pair<int, int> >, greater<pair<int, int> > > pq;

void init(){
edge_cnt = 0;
for (int i = 0; i <= maxn; ++i){
head[i] = -1;
}
}

void add_edge(int a, int b, int c){
u[edge_cnt] = a;
v[edge_cnt] = b;
cnt[edge_cnt] = c;
pre[edge_cnt] = head[a];
head[a] = edge_cnt;
++edge_cnt;
}
void dijkstra(int st){
memset(ans, 0x3f, sizeof ans);
ans[1] = 0;
memset(vis, false, sizeof vis);
pq.push(make_pair(ans[st], st));
while (!pq.empty()){
pair<int, int> fnt = pq.top();
pq.pop();
if (vis[fnt.second] == true){
continue;
}
vis[fnt.second] = true;
for (int i = head[fnt.second]; i != -1; i = pre[i]){
if(ans[v[i]] > ans[u[i]] + cnt[i]){
ans[v[i]] = ans[u[i]] + cnt[i];
pq.push(make_pair(ans[v[i]], v[i]));
}
}
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
while (cin >> T >> N){
int a, b, c;
init();
for (int i = 0; i < T; ++i){
cin >> a >> b >> c;
add_edge(a, b, c);
add_edge(b, a, c);
}
dijkstra(1);
cout << ans[N] << endl;
}
return 0;
}