[hdu2112]最短路

相当于模板题了,用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

你可能感兴趣的:(HDU)