1. 程式人生 > >[POJ3463] Sightseeing(次短路 Heap + Dijkstra)

[POJ3463] Sightseeing(次短路 Heap + Dijkstra)

opened dig [0 pan http con 比較 etc priority

傳送門

用dijkstra比較好,spfa可能有的重復

dis[x][2]:dis[x][0]表示起點到x的最短路、dis[x][1]表示起點到x的次短路;

tot[x][2]:tot[x][0]表示起點到x的最短路條數、tot[x][1]表示起點到x的次短路的條數;

vis[x][2]對應於x和0、1功能為記錄該點是否被訪問!

那麽如何更新最小和次小路呢?顯然我們容易想到下面的方法:

1.if(x<最小)更新最小,次小;
2.else if(x==最小)更新方法數;
3.else if(x<次小)更新次小;
4.else if(x==次小)更新方法數;

——代碼

技術分享
  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 #include <algorithm>
  6 
  7 using namespace std;
  8 
  9 struct heap
 10 {
 11     int x, y, z;
 12     heap(int x = 0, int y = 0, int z = 0) : x(x), y(y), z(z) {}
13 bool operator < (const heap &rhs) const 14 { 15 return y > rhs.y; 16 } 17 }; 18 19 const int MAXM = 10001, MAXN = 1001; 20 int T, n, m, cnt; 21 int dis[MAXN][2], head[MAXN], to[MAXM << 1], next[MAXM << 1], val[MAXM << 1], tot[MAXN][2];
22 priority_queue <heap> q; 23 bool vis[MAXN][2]; 24 25 inline int read() 26 { 27 int x = 0, f = 1; 28 char ch = getchar(); 29 for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1; 30 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0; 31 return x * f; 32 } 33 34 inline void add(int x, int y, int z) 35 { 36 to[cnt] = y; 37 val[cnt] = z; 38 next[cnt] = head[x]; 39 head[x] = cnt++; 40 } 41 42 inline void dijkstra(int s) 43 { 44 int i, u, v, d, p; 45 heap now; 46 memset(vis, 0, sizeof(vis)); 47 memset(tot, 0, sizeof(tot)); 48 memset(dis, 127 / 3, sizeof(dis)); 49 dis[s][0] = 0; 50 tot[s][0] = 1; 51 q.push(heap(s, 0, 0)); 52 while(!q.empty()) 53 { 54 now = q.top(); 55 q.pop(); 56 u = now.x; 57 p = now.z; 58 if(vis[u][p]) continue; 59 vis[u][p] = 1; 60 for(i = head[u]; i ^ -1; i = next[i]) 61 { 62 v = to[i]; 63 if(dis[v][0] > dis[u][p] + val[i]) 64 { 65 dis[v][1] = dis[v][0]; 66 tot[v][1] = tot[v][0]; 67 dis[v][0] = dis[u][p] + val[i]; 68 tot[v][0] = tot[u][p]; 69 q.push(heap(v, dis[v][0], 0)); 70 q.push(heap(v, dis[v][1], 1)); 71 } 72 else if(dis[v][0] == dis[u][p] + val[i]) tot[v][0] += tot[u][p]; 73 else if(dis[v][1] > dis[u][p] + val[i]) 74 { 75 dis[v][1] = dis[u][p] + val[i]; 76 tot[v][1] = tot[u][p]; 77 q.push(heap(v, dis[v][1], 1)); 78 } 79 else if(dis[v][1] == dis[u][p] + val[i]) tot[v][1] += tot[u][p]; 80 } 81 } 82 } 83 84 int main() 85 { 86 int i, j, x, y, z, s, t; 87 T = read(); 88 while(T--) 89 { 90 n = read(); 91 m = read(); 92 cnt = 0; 93 memset(head, -1, sizeof(head)); 94 for(i = 1; i <= m; i++) 95 { 96 x = read(); 97 y = read(); 98 z = read(); 99 add(x, y, z); 100 } 101 s = read(); 102 t = read(); 103 dijkstra(s); 104 if(dis[t][1] == dis[t][0] + 1) tot[t][0] += tot[t][1]; 105 printf("%d\n", tot[t][0]); 106 } 107 }
View Code

[POJ3463] Sightseeing(次短路 Heap + Dijkstra)