题意:给你n个点,m条线,问从1到2 有多少种路径数,要求从a点到b点时,b点到2的距离比a到2的距离近。
思路:
1、找出所有点到2的最短路,,
2、用动态规划的方法,从远到近找出到达i点的路径数。存于ans[i];
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> using namespace std; const int N = 1009; const int M = N*N*2; const int INF = 0x3f3f3f3f; int n,m; struct LT{ int nex,to,dis; } L[M]; int F[N],cnt; void add(int f,int t,int d) { L[cnt].dis = d; L[cnt].nex = F[f]; L[cnt].to = t; F[f] = cnt++; } void init() { int f,t,d; memset(F,0,sizeof(F)); cnt = 1; for(int i=0;i<m;i++) { scanf("%d%d%d",&f,&t,&d); add(f,t,d);add(t,f,d); } } int redis[N];///到终点的最短路 struct nod{ int to,dis; bool operator<(const nod t) const { return dis>t.dis; } }; priority_queue<nod> que; void remindis() { memset(redis,INF,sizeof(redis)); while(!que.empty()) que.pop(); nod e,t;e.dis = 0,e.to = 2; que.push(e); while(!que.empty())///dijkstra { e = que.top();que.pop(); if(redis[e.to]!=INF) continue; redis[e.to] = e.dis; for(int i = F[e.to];i;i = L[i].nex) { int to = L[i].to; if(redis[to]!=INF) continue; t.dis = e.dis+L[i].dis; t.to = to; que.push(t); } } } struct tnod{ int to,dis; bool operator<(const tnod t) const { return dis<t.dis; } }; priority_queue<tnod> tque; int ans[N]; bool visit[N]; void solve() { remindis(); // for(int i=1;i<=n;i++) cout<<redis[i]<<" ";cout<<endl; while(!tque.empty()) tque.pop(); tnod e,t;e.dis=redis[1],e.to = 1; tque.push(e); memset(ans,0,sizeof(ans)); memset(visit,false,sizeof(visit)); visit[1] = true;ans[1]= 1; while(!tque.empty()) { e = tque.top();tque.pop(); // cout<<e.to<<" "<<e.dis<<endl; for(int i=F[e.to];i;i=L[i].nex) { int to =L[i].to; if(redis[to]>=e.dis) continue; if(visit[to]) { ans[to]+=ans[e.to]; continue; } visit[to] = true; ans[to]+=ans[e.to]; t.dis = redis[to]; t.to = to; tque.push(t); } } printf("%d\n",ans[2]); } int main() { freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&m)&&n) { init(); solve(); } return 0; }