题目大意:找出编号为“1”的点到编号为“2”的点的路径数目。满足条件的路径定义为:A点到B点相连,且A到目标点的最短距离大于B到目标的的距离。
做法:从2点开始找出它到其他点的最短距离,然后直接对其进行dfs回溯,求出所有的解。但是这里得注意下,就是dfs过程中,要用到记忆化搜索,将搜索过的点保存下来。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=1005;
const int INF=1<<29;
int Graph[maxn][maxn];
int dist[maxn];
void dijkstra(int st,int n)
{
bool s[maxn];
for(int i=1;i<=n;i++)
{
dist[i]=Graph[st][i];
s[i]=0;
}
s[st]=1;
dist[st]=0;
for(int i=2;i<=n;i++)
{
int mindist=INF;
int u=st;
for(int j=1;j<=n;j++)
if(!s[j] && dist[j]<mindist)
{
u=j;
mindist=dist[j];
}
s[u]=1;
for(int j=1;j<=n;j++)
if(!s[j] && Graph[u][j]!=INF && Graph[u][j]+dist[u]<dist[j])
dist[j]=dist[u]+Graph[u][j];
}
}
int dp[maxn];
int dfs(int k,int n)
{
if(dp[k])return dp[k];
if(k==2)return 1;
for(int i=1;i<=n;i++)
if(Graph[k][i]!=INF && dist[k]>dist[i])
dp[k]+=dfs(i,n);
return dp[k];
}
int main()
{
int n,m;
int a,b,d;
// freopen("in.txt","r",stdin);
while(scanf("%d",&n) && n)
{
scanf("%d",&m);
memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
Graph[i][j]=INF;
Graph[i][i]=0;
}
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&a,&b,&d);
Graph[a][b]=Graph[b][a]=d;
}
dijkstra(2,n);
int res=dfs(1,n);
printf("%d\n",res);
}
return 0;
}