hdu 1142 A Walk Through the Forest
http://acm.hdu.edu.cn/showproblem.php?pid=1142
The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take.
1.1为起点,2为终点,因为要走ab路时,必须保证那个条件,所以从终点开始使用单源最短路Dijkstra算法,就得到了最短的一条路,作为找路的最低限度。
2.然后深搜每条路,看看满足题意的路径有多少条。当然,这个需要从起点开始搜,因为dis[i]数组中保存的都是该点到终点的最短距离。
3.这样搜索之后,dp[1]就是从起点到终点所有满足题意的路径的条数。
#include<iostream>
using namespace std;
#define INF 9999999
#define MAX 1001
int map[MAX][MAX];
int dis[MAX],v[MAX],sum[MAX];
void dijkstra(int s,int n)
{
int i,j,min,k;
for(i=1;i<=n;i++)
dis[i]=map[s][i];
memset(v,0,sizeof(v));
v[s]=1;
dis[s]=0;
for(i=2;i<=n;i++)
{
k=s;
min=INF;
for(j=1;j<=n;j++)
if(!v[j]&&min>dis[j])
{
min=dis[j];
k=j;
}
v[k]=1;
for(j=1;j<=n;j++)
if(!v[j]&&dis[j]>dis[k]+map[k][j])
dis[j]=dis[k]+map[k][j];
}
}
int dfs(int s,int n)
{
int i;
if(sum[s])
return sum[s];
if(s==2)
return 1;
for(i=1;i<=n;i++)
if(map[s][i]!=INF)
{
if(dis[s]>dis[i])
sum[s]+=dfs(i,n);
}
return sum[s];
}
int main()
{
int n,m;
while(~scanf("%d",&n),n)
{
scanf("%d",&m);
int a,b,q;
int i,j;
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
map[i][j]=INF;
while(m--)
{
scanf("%d%d%d",&a,&b,&q);
if(map[a][b]==INF||map[a][b]>q)
map[a][b]=map[b][a]=q;
}
dijkstra(2,n);
memset(sum,0,sizeof(sum));
printf("%d\n",dfs(1,n));
}
return 0;
}