题意 :办公室编号为1,家编号为2,问从办公室到家有多少条路径,当然路径要短,从A走到B的条件是,A到家比B到家要远,所以可以从A走向B 。
思路 : 先以终点为起点求最短路,然后记忆化搜索。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 //1142 2 #include <cstdio> 3 #include <queue> 4 #include <cstring> 5 #include <iostream> 6 const int INF = 1 << 28 ; 7 using namespace std ; 8 9 int N,M ; 10 int mapp[1100][1100] ,pre[1100],dist[1100]; 11 bool vis[1100] ; 12 13 void spfa(int src) 14 { 15 for(int i = 1 ; i <= N ; i++) 16 { 17 vis[i] = false ; 18 dist[i] = INF ; 19 } 20 queue<int>Q ; 21 dist[src] = 0 ; 22 vis[src] = true ; 23 Q.push(src) ; 24 while(!Q.empty()) 25 { 26 int u = Q.front() ; 27 Q.pop() ; 28 vis[u] = false ; 29 for(int i = 1 ; i <= N ; i++) 30 { 31 if(dist[i] > dist[u] + mapp[u][i] && mapp[u][i] != INF) 32 { 33 dist[i] = dist[u] + mapp[u][i] ; 34 if(!vis[i]) 35 { 36 vis[i] = true ; 37 Q.push(i) ; 38 } 39 } 40 } 41 } 42 } 43 int dfs(int s) 44 { 45 if(pre[s]) return pre[s]; 46 if(s == 2) return 1; 47 int cnt = 0 ; 48 for(int i = 1 ;i <= N ; i++) 49 { 50 if(mapp[s][i] < INF && dist[s] > dist[i]) 51 { 52 if(pre[i]) cnt += pre[i];//已经找过了 53 else cnt += dfs(i); 54 } 55 } 56 pre[s] = cnt ; 57 return pre[s]; 58 } 59 void Init() 60 { 61 for(int i = 1 ; i <= N ; i++) 62 for(int j = 1 ; j <= N ; j++) 63 { 64 if(i == j) mapp[i][j] = 0 ; 65 else mapp[i][j] = INF ; 66 } 67 memset(pre,0,sizeof(pre)) ; 68 } 69 int main() 70 { 71 while(cin >> N) 72 { 73 if(N == 0) break ; 74 cin >> M ; 75 Init() ; 76 int u,v,w ; 77 while(M--) 78 { 79 cin >> u >> v >> w ; 80 mapp[u][v] = mapp[v][u] = w ; 81 } 82 spfa(2) ; 83 cout << dfs(1) << endl ; 84 } 85 return 0 ; 86 }