首先用迪杰斯特拉算法求出各点到2的最短距离,然后用记忆化搜索算出 各点到2的可能路径数dp[i]
AC代码如下:
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
#define MAX 0x3f3f3f3f
typedef struct{
int to, next, weight;
}Edge;
Edge edge[2000000];
int head[1010], tot;
int N;
int dis[1010], weight[1010][1010];
long long ans;
bool visit[1010];
int dp[1010];
void calc_min_dis(){
memset( dis, 0x3f, sizeof( dis ) );
for( int i = head[2]; i != -1; i = edge[i].next ){
int to = edge[i].to;
dis[to] = edge[i].weight;
}
bool mark[1010];
memset( mark, false, sizeof( mark ) );
mark[2] = true;
for( int i = 1; i < N; i++ ){
int k = 1, mindis = MAX;
for( int j = 1; j <= N; j++ ){
if( !mark[j] && dis[j] < mindis ){
mindis = dis[j];
k = j;
}
}
mark[k] = true;
for( int j = 1; j <= N; j++ ){
if( !mark[j] && weight[j][k] + dis[k] < dis[j] ){
dis[j] = weight[j][k] + dis[k];
}
}
}
dis[2] = 0;
}
void add_edge( int a, int b, int weight ){
edge[tot].to = b;
edge[tot].weight = weight;
edge[tot].next = head[a];
head[a] = tot++;
edge[tot].to = a;
edge[tot].weight = weight;
edge[tot].next = head[b];
head[b] = tot++;
}
int DFS( int pos ){
if( pos == 2 ){
return 1;
}
if( dp[pos] != -1 ){
return dp[pos];
}
int ans = 0;
for( int i = head[pos]; i != -1; i = edge[i].next ){
int to = edge[i].to;
if( dis[to] < dis[pos] ){
ans += DFS( to );
}
}
return dp[pos] = ans;
}
int main(){
int M;
while( cin >> N && N ){
cin >> M;
tot = 0;
memset( head, -1, sizeof( head ) );
memset( weight, 0x3f, sizeof( weight ) );
for( int i = 0; i < M; i++ ){
int temp1, temp2, temp3;
cin >> temp1 >> temp2 >> temp3;
weight[temp1][temp2] = weight[temp2][temp1] = temp3;
add_edge( temp1, temp2, temp3 );
}
calc_min_dis();
memset( dp, -1, sizeof( dp ) );
int ans = DFS( 1 );
cout << ans << endl;
}
return 0;
}