题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1142
题意:问从office到home有多少路可以走,下一步到家的最小距离必须比现在到家的最短距离小才能到下一步。
思路:先处理出各个点到home的最短距离,再用dfs+记忆化搜索
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#define maxn 1005
#define inf 100000
using namespace std;
int n, m, ans;
int Map[maxn][maxn];
bool vis[maxn];
int dp[maxn];
int dist[maxn];
void pre()
{
memset(vis, 0, sizeof(vis));
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
Map[i][j] = inf;
}
}
}
void Dijkstra(int cur = 2)
{
vis[cur] = 1;
for(int i = 1; i <= n; i++)
dist[i] = Map[cur][i];
dist[cur] = 0;
for(int i = 2; i <= n; i++)
{
int k = cur;
int minval = inf;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && dist[j] < minval)
{
minval = dist[j];
k = j;
}
}
vis[k] = 1;
for(int j = 1; j <= n; j++)
{
if(!vis[j])
dist[j] = min(dist[j], dist[k] + Map[k][j]);
}
}
}
int DFS(int node)
{
if(dp[node])
{
return dp[node];
}
int ans = 0;
for(int i = 1; i <= n; i++)
{
if(Map[node][i] != inf && dist[i] < dist[node])
{
ans += DFS(i);
}
}
return dp[node] = ans;
}
int main()
{
while(~scanf("%d", &n) && n)
{
scanf("%d", &m);
pre();
for(int i = 0; i < m; i++)
{
int s, e, dis;
scanf("%d %d %d", &s, &e, &dis);
Map[s][e] = Map[e][s] = dis;
}
Dijkstra();
dp[2] = vis[1] = 1;
ans = DFS(1);
cout << ans << endl;
}
return 0;
}