【HDOJ】1688 Sightseeing
Dijkstra求解次短路径,使用cnt和dis数组记录最小、次小的个数和长度。重写更新操作。
1 /* 1688 */ 2 #include <iostream> 3 #include <string> 4 #include <map> 5 #include <queue> 6 #include <set> 7 #include <vector> 8 #include <algorithm> 9 #include <cstdio> 10 #include <cmath> 11 #include <cstring> 12 #include <climits> 13 #include <cctype> 14 using namespace std; 15 16 #define MAXN 1005 17 #define INF 0x3f3f3f3f 18 19 typedef struct Edge_t { 20 int v, w; 21 Edge_t() {} 22 Edge_t(int u, int ww) { 23 v = u; w = ww; 24 } 25 } Edge_t; 26 27 vector<Edge_t> vc[MAXN]; 28 bool visit[MAXN][2]; 29 int dis[MAXN][2]; 30 int cnt[MAXN][2]; 31 int n, m; 32 33 void init() { 34 int i; 35 36 for (i=1; i<=n; ++i) 37 vc[i].clear(); 38 memset(cnt, 0, sizeof(cnt)); 39 } 40 41 int dijkstra(int s, int f) { 42 int i, j, k, tmp, r; 43 int u, v, w, mmin; 44 int ret = 0; 45 Edge_t e; 46 47 memset(visit, false, sizeof(visit)); 48 memset(dis, 0x3f, sizeof(dis)); 49 dis[s][0] = 0; 50 cnt[s][0] = 1; 51 52 for (r=0; r<n*2; ++r) { 53 mmin = INF; 54 u = -1; 55 for (j=1; j<=n; ++j) { 56 if (!visit[j][0] && dis[j][0]<mmin) { 57 mmin = dis[j][0]; 58 u = j; 59 k = 0; 60 } else if (!visit[j][1] && dis[j][1]<mmin) { 61 mmin = dis[j][1]; 62 u = j; 63 k = 1; 64 } 65 } 66 if (u == -1) 67 break; 68 visit[u][k] = true; 69 for (i=0; i<vc[u].size(); ++i) { 70 e = vc[u][i]; 71 v = e.v; 72 w = e.w; 73 tmp = w + dis[u][k]; 74 if (tmp < dis[v][0]) { 75 dis[v][1] = dis[v][0]; 76 cnt[v][1] = cnt[v][0]; 77 dis[v][0] = tmp; 78 cnt[v][0] = cnt[u][k]; 79 } else if (tmp == dis[v][0]) { 80 cnt[v][0] += cnt[u][k]; 81 } else if (tmp < dis[v][1]) { 82 dis[v][1] = tmp; 83 cnt[v][1] = cnt[u][k]; 84 } else if (tmp == dis[v][1]) { 85 cnt[v][1] += cnt[u][k]; 86 } 87 } 88 } 89 90 ret += cnt[f][0]; 91 if (dis[f][0]+1 == dis[f][1]) 92 ret += cnt[f][1]; 93 return ret; 94 } 95 96 int main() { 97 int t; 98 int i, j, k; 99 Edge_t e; 100 101 #ifndef ONLINE_JUDGE 102 freopen("data.in", "r", stdin); 103 freopen("data.out", "w", stdout); 104 #endif 105 106 scanf("%d", &t); 107 while (t--) { 108 scanf("%d %d", &n, &m); 109 init(); 110 while (m--) { 111 scanf("%d %d %d", &i, &e.v, &e.w); 112 vc[i].push_back(e); 113 } 114 scanf("%d %d", &i, &j); 115 k = dijkstra(i, j); 116 printf("%d\n", k); 117 } 118 119 return 0; 120 }