题意:给你n各点,m行关于这些点的联通关系,以及距离,求从1这个点到2这个点之间,下一个点到2这个点比当前点到2这个点的距离要小的路径的条数......

思路:dj+记忆化搜索.......

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
typedef __int64 ss;
#define max 1010
#define p 10000000
ss a[max][max];
ss n,m;
ss dp[max],dist[max];
void dj(ss n,ss v,ss v1)
{
ss i,j,k,min;
ss s[max];
for(i=1;i<=n;i++)
{
dist[i]=a[v][i];
s[i]=0;
}
s[v]=1;
for(i=2;i<=n;i++)
{
min=p;
k=1;
for(j=1;j<=n;j++)
if(s[j]==0&&dist[j]<min)
{
k=j;
min=dist[j];
}
s[k]=1;
for(j=1;j<=n;j++)
if(s[j]==0)
if(a[k][j]<p&&dist[k]+a[k][j]<dist[j])
dist[j]=dist[k]+a[k][j];
}
}
ss dfs(ss num)
{
if(dp[num]) return dp[num];
if(num==2) return 1;
ss sum=0;
for(ss i=1;i<=n;i++)
{
if(i==num)
continue;
if(a[num][i]!=p&&dist[num]>dist[i])
{
sum+=dfs(i);
}
}
dp[num]=sum;
return dp[num];
}
int main()
{
while(scanf("%I64d",&n)>0&&n)
{
scanf("%I64d",&m);
for(ss i=0;i<=n;i++)
for(ss j=0;j<=n;j++)
a[i][j]=p;
for(ss i=0;i<=n;i++)
a[i][i]=0;
for(ss i=1;i<=m;i++)
{
ss tmp,x,y;
scanf("%I64d%I64d%I64d",&x,&y,&tmp);
if(a[x][y]>tmp)
{
a[x][y]=a[y][x]=tmp;
}
}
dj(n,2,1);
//for(int i=1;i<=n;i++)
//printf("%I64d\n",dist[i]);
memset(dp,0,sizeof(dp));
printf("%I64d\n",dfs(1));
}
return 0;
}
05-12 15:26