相当于模板题了,用trie来完成字符串到数字的映射比map<string, int>要快不少,令外可以考虑hash。
运行时间对比:
(1)(2)600ms左右 (3)3000ms左右(4)1500ms左右
(1)O(n^2)的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
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <map>
using
namespace
std;
#define umin(a, b) if ((a) > (b)) (a) = (b)
const
int
maxn = 157;
int
n;
struct
Trie {
int
ch[maxn * 32][26];
int
val[maxn * 32], sz;
void
init() {
memset
(val, 0,
sizeof
(val));
memset
(ch[0], 0,
sizeof
(ch[0]));
sz = 0;
}
int
insert(
char
*s) {
int
i = 0, j = 0;
for
(; s[j]; i = ch[i][s[j]], j ++) {
if
(s[j] <
'a'
) s[j] -=
'A'
;
else
s[j] -=
'a'
;
if
(!ch[i][s[j]]) {
ch[i][s[j]] = ++ sz;
memset
(ch[sz], 0,
sizeof
(ch[sz]));
}
}
if
(!val[i]) val[i] = ++ n;
return
val[i];
}
} trie;
int
dist[maxn][maxn], d[maxn];
bool
vis[maxn];
int
main()
{
#ifndef ONLINE_JUDGE
freopen
(
"in.txt"
,
"r"
, stdin);
#endif // ONLINE_JUDGE
int
m;
char
s1[40], s2[40];
int
t;
while
(cin >> m, ~m) {
n = 0;
trie.init();
scanf
(
"%s%s"
, s1, s2);
trie.insert(s1);
t = trie.insert(s2);
memset
(dist, 0x3f,
sizeof
(dist));
for
(
int
i = 0; i < m; i ++) {
int
x;
scanf
(
"%s%s%d"
, s1, s2, &x);
int
u = trie.insert(s1), v = trie.insert(s2);
umin(dist[u][v], x);
umin(dist[v][u], x);
}
memset
(vis, 0,
sizeof
(vis));
memset
(d, 0x3f,
sizeof
(d));
d[1] = 0;
for
(
int
i = 1; i < n; i ++) {
int
pos = 0, mind = 0x3f3f3f3f;
for
(
int
j = 1; j <= n; j ++) {
if
(!vis[j] && d[j] < mind) {
mind = d[j];
pos = j;
}
}
if
(!pos)
break
;
vis[pos] =
true
;
for
(
int
j = 1; j <= n; j ++) {
if
(!vis[j]) umin(d[j], d[pos] + dist[pos][j]);
}
}
printf
(
"%d\n"
, d[t] == 0x3f3f3f3f? -1 : d[t]);
}
return
0;
}
|
(2)SPFA:
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <map>
using
namespace
std;
#define umin(a, b) if ((a) > (b)) (a) = (b)
const
int
maxn = 157;
int
n;
struct
Trie {
int
ch[maxn * 32][26];
int
val[maxn * 32], sz;
void
init() {
memset
(val, 0,
sizeof
(val));
memset
(ch[0], 0,
sizeof
(ch[0]));
sz = 0;
}
int
insert(
char
*s) {
int
i = 0, j = 0;
for
(; s[j]; i = ch[i][s[j]], j ++) {
if
(s[j] <
'a'
) s[j] -=
'A'
;
else
s[j] -=
'a'
;
if
(!ch[i][s[j]]) {
ch[i][s[j]] = ++ sz;
memset
(ch[sz], 0,
sizeof
(ch[sz]));
}
}
if
(!val[i]) val[i] = ++ n;
return
val[i];
}
} trie;
vector<vector<
int
> >G, W;
queue<
int
> Q;
int
d[maxn];
bool
mark[maxn];
bool
relax(
int
u,
int
v,
int
w) {
if
(d[v] > d[u] + w) {
d[v] = d[u] + w;
return
true
;
}
return
false
;
}
int
main()
{
#ifndef ONLINE_JUDGE
freopen
(
"in.txt"
,
"r"
, stdin);
#endif // ONLINE_JUDGE
int
m;
char
s1[40], s2[40];
int
t;
while
(cin >> m, ~m) {
n = 0;
trie.init();
scanf
(
"%s%s"
, s1, s2);
trie.insert(s1);
t = trie.insert(s2);
G.clear();
W.clear();
G.resize(maxn + 2);
W.resize(maxn + 2);
for
(
int
i = 0; i < m; i ++) {
int
x;
scanf
(
"%s%s%d"
, s1, s2, &x);
int
u = trie.insert(s1), v = trie.insert(s2);
G[u].push_back(v);
G[v].push_back(u);
W[u].push_back(x);
W[v].push_back(x);
}
while
(!Q.empty()) Q.pop();
Q.push(1);
memset
(d, 0x3f,
sizeof
(d));
memset
(mark, 0,
sizeof
(mark));
mark[1] =
true
;
d[1] = 0;
while
(!Q.empty()) {
int
h = Q.front(); Q.pop();
for
(
int
i = 0; i < G[h].size(); i ++) {
int
v = G[h][i], r = relax(h, v, W[h][i]);
if
(!mark[v] && r) {
mark[v] =
true
;
Q.push(v);
}
}
mark[h] =
false
;
}
printf
(
"%d\n"
, d[t] == 0x3f3f3f3f? -1 : d[t]);
}
return
0;
}
|
(3)map + cin :
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
74
75
76
|
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#include <map>
using
namespace
std;
const
int
maxn = 2e4 +7;
map<string,
int
> mp;
int
n;
vector<vector<
int
> >G, W;
queue<
int
> Q;
bool
mark[maxn];
int
d[maxn];
bool
relax(
int
u,
int
v,
int
w) {
if
(d[v] > d[u] + w) {
d[v] = d[u] + w;
return
true
;
}
return
false
;
}
int
main()
{
#ifndef ONLINE_JUDGE
freopen
(
"in.txt"
,
"r"
, stdin);
#endif // ONLINE_JUDGE
string s1, s2, S;
int
x, m;
while
(cin >> m, ~m) {
cin >> s1 >> s2;
S = s2;
n = 1;
mp.clear();
G.clear();
W.clear();
G.resize(maxn + 2);
W.resize(maxn + 2);
if
(!mp[s1]) mp[s1] = n ++;
if
(!mp[s2]) mp[s2] = n ++;
for
(
int
i = 0; i < m; i ++) {
cin >> s1 >> s2 >> x;
if
(!mp[s1]) mp[s1] = n ++;
if
(!mp[s2]) mp[s2] = n ++;
G[mp[s1]].push_back(mp[s2]);
G[mp[s2]].push_back(mp[s1]);
W[mp[s1]].push_back(x);
W[mp[s2]].push_back(x);
}
while
(!Q.empty()) Q.pop();
Q.push(1);
memset
(d, 0x3f,
sizeof
(d));
memset
(mark, 0,
sizeof
(mark));
mark[1] =
true
;
d[1] = 0;
while
(!Q.empty()) {
int
h = Q.front(); Q.pop();
for
(
int
i = 0; i < G[h].size(); i ++) {
int
v = G[h][i], r = relax(h, v, W[h][i]);
if
(!mark[v] && r) {
mark[v] =
true
;
Q.push(v);
}
}
mark[h] =
false
;
}
printf
(
"%d\n"
, d[mp[S]] == 0x3f3f3f3f? -1 : d[mp[S]]);
}
return
0;
}
|
(4)map + scanf:
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
|