这道题用到了最短路和dp的知识,感觉是一道不错的题目
首先根据原题所提供的图,已2为起点求一次单源最短路径,然后再根据题目所说的,当d[i]>d[j]时则可以从i到j,所以可以按照这个要求建另外一个图,这个图就是很典型的一个“数塔”模型了,所以再dp一下,就可以求出路线数。
具体看代码实现。
#include<iostream> #include<cstdio> #include<vector> using namespace std; const int maxn=1005; const int INF=(1<<30); vector<int>edge[maxn];//存储能走的边 int map[maxn][maxn];//原始图 int d[maxn];//d[i]表示i到2的距离 int dp[maxn];//dp[i]表示从i到2的路径数 bool visit[maxn]; void dfs(int v) { if(dp[v]!=-1) return; dp[v]=0; for(int i=0;i<edge[v].size();i++) { int u=edge[v][i]; dfs(u); dp[v]+=dp[u]; } } int main() { int i,j,n,m; int a,b,c; while(scanf("%d",&n),n) { scanf("%d",&m); for(i=1;i<=n;i++) { visit[i]=false; d[i]=INF; for(j=1;j<=n;j++) map[i][j]=INF; } d[2]=0; while(m--) { scanf("%d%d%d",&a,&b,&c); if(map[a][b]>c) { map[a][b]=c; map[b][a]=c; } } d[0]=INF; while(1) { j=0; for(i=1;i<=n;i++) if(!visit[i]&&d[i]<d[j]) j=i; if(j==0) break; visit[j]=true; for(i=1;i<=n;i++) if(!visit[i]&&d[j]+map[j][i]<d[i]) d[i]=d[j]+map[j][i]; } for(i=1;i<=n;i++) edge[i].clear(); for(i=1;i<=n;i++) for(j=1;j<=n;j++) if(map[i][j]!=INF&&d[i]>d[j]) edge[i].push_back(j); for(i=1;i<=n;i++) dp[i]=-1; dp[2]=1; dfs(1); printf("%d\n",dp[1]); } return 0; }