http://acm.hdu.edu.cn/showproblem.php?pid=1142
题解:
看样子很多人都把这题目看错了,以为是求最短路的条数。真正的意思是:假设 A 和 B 是相连的,当前在 A 处,如果 A 到终点的距离大于 B 到终点的距离,
则可以从 A 通往 B 处,问满足这种的条件的路径条数。
分析:
1、以终点 2 为起点 dijkstra;
2、直接DFS记忆化搜索。
/*
*@Author: STZG
*@Language: C++
*/
//#include <bits/stdc++.h>
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<bitset>
#include<queue>
#include<deque>
#include<stack>
#include<cmath>
#include<list>
//#include<map>
#include<set>
//#define DEBUG
#define RI register int
using namespace std;
typedef long long ll;
typedef __int128 lll;
const int N=1010;
const int MOD=1e9+7;
const double PI = acos(-1.0);
const double EXP = 1E-8;
const int INF = 0x3f3f3f3f;
int t,n,m,k,q;
int map[N][N];
bool vis[N];
int dist[N];
int p[N];
void init(){
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
map[i][j]=(i==j?0:INF);
memset(p,0,sizeof(p));
memset(vis,false,sizeof(vis));
memset(dist,0,sizeof(dist));
}
void Dijkstra(){
for(int i=1;i<=n;i++){
dist[i]=map[2][i];
}
dist[2]=0;
vis[2]=1;
for(int i=1;i<n;i++){
int minl=INF,k=0;
for(int j=1;j<=n;j++){
if(!vis[j]&&dist[j]<minl){
minl=dist[j];
k=j;
}
}
if(k==0)
break;
vis[k]=1;
for(int j=1;j<=n;j++){
if(!vis[j]&&dist[j]>map[k][j]+minl){
dist[j]=map[k][j]+minl;
}
}
}
}
int DFS(int s){
if(p[s])return p[s];
if(s==2)return 1;
int sum=0;
for(RI i=1;i<=n;i++){
if(map[s][i]<INF&&dist[s]>dist[i]){
if(p[i])
sum+=p[i];
else
sum+=DFS(i);
}
}
p[s]+=sum;
return p[s];
}
int main()
{
#ifdef DEBUG
freopen("input.in", "r", stdin);
//freopen("output.out", "w", stdout);
#endif
while(~scanf("%d",&n)&&n){
scanf("%d",&m);
init();
int a,b,d;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&a,&b,&d);
map[a][b]=map[b][a]=d;
}
Dijkstra();
cout<<DFS(1)<<endl;
}
//cout << "Hello world!" << endl;
return 0;
}