求出办公室到每一点的最短路d[i],然后记忆话搜索,dp[i]由和i点相邻且d[j]<d[i]的点更新,是树形DP
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#define INF 10000000
using namespace std;
int N,M;
struct edge{
int s,t,c;
};
vector <edge> E;
vector <int> G[1005];
int d[1005];
bool vis[1005];
int p[1005];
int dp[1005];
int solve(int n){
if(dp[n]) return dp[n];
for(int i=0;i<G[n].size();i++){
edge &tmp=E[G[n][i]];
if(d[tmp.t]<d[n]){
dp[n]+=solve(tmp.t);
}
}
return dp[n];
}
void addedge(int s,int t,int cost){
E.push_back(edge{s,t,cost});
G[s].push_back(E.size()-1);
}
struct HNode{
int d,u;
bool operator <(const HNode &obj)const{
return d>obj.d;
}
};
void Dij(int s){
for(int i=1;i<=N;i++){
d[i]=INF;
}
d[s]=0;
memset(vis,0,sizeof(vis));
priority_queue<HNode> Q;
Q.push(HNode{0,s});
while(!Q.empty()){
int u=Q.top().u;
Q.pop();
if(vis[u]) continue;
vis[u]=1;
for(int i=0;i<G[u].size();i++){
edge &tmp=E[G[u][i]];
if(d[tmp.t]>d[u]+tmp.c){
d[tmp.t]=d[u]+tmp.c;
p[tmp.t]=u;
Q.push(HNode{d[tmp.t],tmp.t});
}
}
}
}
int main(){
while(~scanf("%d",&N)){
for(int i=1;i<=N;i++){
G[i].clear();
}
E.clear();
if(!N) break;
scanf("%d",&M);
for(int i=0;i<M;i++){
int s,t,c;
scanf("%d%d%d",&s,&t,&c);
addedge(s,t,c);
addedge(t,s,c);
}
Dij(2);
memset(dp,0,sizeof(dp));
dp[2]=1;
solve(1);
for(int i=1;i<=N;i++){
//cout<<i<<' '<<dp[i]<<endl;
}
printf("%d\n",solve(1));
}
return 0;
}