题意:
办公室(起点)的编号为1,家(目的地)编号为2。给你一些编号之间的距离。问你,若当前所在的位置A,与B(必须是连通的)所能到达目的地的最短路径远些,那么就可从A走到B,那么满足这样的条件,有多少条路径。
分析:
根据题意,要判断能否可以走,必须知道当前点到目的地的最短距离,那么,我们只要从目的地出发,搜索最短路就可以了。(最好不要用dijkstra).
然后,在进行记忆搜索就行了。
我用了两种方法。用dijkstra超时了。还是spfa过了。
#include<cstdio>
#include<queue>
#define INF 1000000000
using namespace std;
const int N=1005;
int vis[N],map[N][N],dis[N],e[N];
int n;
/*
void dijsktra(int p)
{
for(int i=1;i<=n;i++){
dis[i]=map[p][i];
vis[i]=0;
}
dis[p]=0,vis[p]=1;
for(int i=1;i<n;i++){
int k=p;
int d=INF;
for(int j=1;j<=n;j++){
if(!vis[j]&&dis[j]<d){
k=j;
d=dis[j];
}
vis[k]=1;
for(int j=1;j<=n;j++)
if(!vis[j]&&map[k][j]<INF&&map[k][j]+dis[k]<dis[j]){
dis[j]=map[k][j]+dis[k];
}
}
}
}*/
void spfa(int p)
{
queue<int>Q;
for(int i=1;i<=n;i++){
dis[i]=INF;
vis[i]=0;
}
dis[p]=0,vis[p]=1;
Q.push(p);
while(!Q.empty()){
int v=Q.front();
Q.pop();
vis[v]=0;
for(int i=1;i<=n;i++){
if(map[v][i]+dis[v]<dis[i]){
dis[i]=map[v][i]+dis[v];
if(!vis[i]){
vis[i]=1;
Q.push(i);
}
}
}
}
}
int DFS(int p)
{
if(e[p]) return e[p];
if(p==2) return 1;
int ans=0;
for(int i=1;i<=n;i++){
if(map[p][i]<INF&&dis[p]>dis[i])
if(e[i]) ans+=e[i];
else ans+=DFS(i);
}
e[p]=ans;
return e[p];
}
int main()
{
int i,j,x,y,m,k;
while(scanf("%d",&n),n){
scanf("%d",&m);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++){
map[i][j]=INF;
e[i]=0;
}
for(i=0;i<m;i++){
scanf("%d %d %d",&x,&y,&k);
map[x][y]=map[y][x]=k;
}
//dijsktra(2);
spfa(2);
printf("%d\n",DFS(1));
}
return 0;
}