题意: 在一个森林中从办公室走到房子。
因为要在晚上之前回家 所以不能走比你自己的位置离终点的最短路还要长的点。
找出能走到终点的路的条数
思路: 先从终点开始搜一遍最短路。 然后再从起点开始搜。
最短路比你自己这个点更短的才可以搜
挂上代码。
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define INF 2000000000
using namespace std;
long long a[1005][1005];
int u[1005];
long long d[1005];
int k[1005];
int N;
int bo[1005];
void dij(int s)
{
memset(u,0,sizeof(u));
for(int i=1;i<=1000;i++)
d[i]=INF;
d[s]=0;
k[s]=1;
while(1)
{
int v=-1;
for(int i=1;i<=1000;i++)
{
if(u[i]==0&&(v==-1||d[i]<d[v]))
v=i;
}
if(v==-1) break;
u[v]=1;
//cout<<v<<endl;
for(int i=1;i<=1000;i++)
{
d[i]=min(d[i],d[v]+a[v][i]);
}
}
}
void dij1(int s)
{
memset(u,0,sizeof(u));
memset(k,0,sizeof(k));
k[s]=1;
while(1)
{
int v=-1;
for(int i=1;i<=1000;i++)
{
if(u[i]==0&&(v==-1||d[i]>d[v])&&k[i]!=0)
v=i;
}
if(v==-1) break;
u[v]=1;
//cout<<v<<endl;
for(int i=1;i<=1000;i++)
{
if(a[v][i]!=INF&&d[i]<d[v])
k[i]+=k[v];
}
}
}
int main()
{
int M;
while(scanf("%d",&N)!=EOF)
{ if(N==0) return 0;
scanf("%d",&M);
for(int i=1;i<=1000;i++)
for(int j=1;j<=1000;j++)
a[i][j]=INF;
int pi=0;
while(M--)
{
int A,B;
long long C;
scanf("%d%d%I64d",&A,&B,&C);
a[A][B]=min(C,a[A][B]);
a[B][A]=min(C,a[B][A]);
}
dij(2);
dij1(1);
printf("%d\n",k[2]);
}
}