http://acm.split.hdu.edu.cn/showproblem.php?pid=1142
根据题意,将2看成起点反向思考,spfa求出所有点到2的最短路径,在从1开始用记忆化dfs以1为起点找1到2的不同的路
#include<bits/stdc++.h>
using namespace std;
struct r{
int ed,va;
};
r road[1111];
vector<r> po[1111];
int dp[1111],dis[1111];
bool vis[1111];int n,m;
void spfa(int st)
{
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
dis[i]=0x3fffffff;
queue<int> q;
q.push(st);
dis[st]=0;
vis[st]=1;
while(!q.empty())
{
st=q.front();
q.pop();
vis[st]=0;
for(int i=0;i<po[st].size();i++)
{
int end=po[st][i].ed;
int val=po[st][i].va;
if(dis[st]+val<dis[end])
{
dis[end]=dis[st]+val;
if(vis[end]==0)
{
q.push(end);
vis[end]=1;
}
}
}
}
}
void add(int u,int v,int w)
{
r x;
x.ed=v;x.va=w;
po[u].push_back(x);
}
int dfs(int st)
{
if(st==2)return 1;
if(dp[st]>0)
return dp[st];
for(int i=0;i<po[st].size();i++)
{
int end=po[st][i].ed;
if (dis[end]<dis[st])
dp[st]+= dfs(end);
}
return dp[st];
}
int main(){
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
po[i].clear();
if(n==0)break;
cin>>m;
int i;
int u,v,w;
for(i=1;i<=m;i++)
{
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
spfa(2);
memset(dp,0,sizeof(dp));
int ans=dfs(1);
printf("%d\n",ans);
}
return 0;
}