先求一遍最短路,然后判断哪条路可以走再记忆化搜索统计方法数。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdio> 5 using namespace std; 6 7 const int INF = 99999999; 8 const int N = 1001; 9 const int M = N * N; 10 int head[N]; 11 int dist[N]; 12 int dp[N]; 13 bool visit[N]; 14 int n, m, e; 15 16 struct Edge 17 { 18 int v, next, w; 19 } edge[M]; 20 21 void addEdge( int u, int v, int w ) 22 { 23 edge[e].v = v; 24 edge[e].w = w; 25 edge[e].next = head[u]; 26 head[u] = e++; 27 } 28 29 void dij( int s ) 30 { 31 memset( visit, false, sizeof(visit) ); 32 for ( int i = 0; i <= n; i++ ) 33 { 34 dist[i] = INF; 35 } 36 dist[s] = 0; 37 for ( int i = 1; i <= n; i++ ) 38 { 39 int u = 0; 40 for ( int j = 1; j <= n; j++ ) 41 { 42 if ( !visit[j] && dist[j] < dist[u] ) 43 { 44 u = j; 45 } 46 } 47 visit[u] = true; 48 for ( int j = head[u]; j != -1; j = edge[j].next ) 49 { 50 int v = edge[j].v, w = edge[j].w; 51 if ( !visit[v] && dist[u] + w < dist[v] ) 52 { 53 dist[v] = dist[u] + w; 54 } 55 } 56 } 57 } 58 59 int dfs( int u ) 60 { 61 if ( dp[u] ) return dp[u]; 62 int sum = 0; 63 for ( int i = head[u]; i != -1; i = edge[i].next ) 64 { 65 int v = edge[i].v; 66 if ( dist[u] > dist[v] ) 67 { 68 sum += dfs(v); 69 } 70 } 71 return dp[u] = sum; 72 } 73 74 int main () 75 { 76 while ( scanf("%d", &n), n ) 77 { 78 e = 0; 79 memset( head, -1, sizeof(head) ); 80 scanf("%d", &m); 81 while ( m-- ) 82 { 83 int u, v, w; 84 scanf("%d%d%d", &u, &v, &w); 85 addEdge( u, v, w ); 86 addEdge( v, u, w ); 87 } 88 dij(2); 89 memset( dp, 0, sizeof(dp) ); 90 dp[2] = 1; 91 int ans = dfs(1); 92 printf("%d ", ans); 93 } 94 return 0; 95 }