这道题用到了最短路和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;
}