一直忘了来更新了……先放个water。
题目大意:从点1出发,每次只能选择比当前点更接近点2的点移动,问一共有多少种走法。
思路:先用spfa或者其他最短路算法算出所有点到点2的距离,之后从点1搜索即可。
我用的spfa找最短路之后记忆化搜索。
1 #include <cstdio>
2 #include <iostream>
3 #include <queue>
4
5 #define SIZE 50000
6 #define INF 0x3F3F3F3F
7 using namespace std;
8 struct path
9 {
10 int to,next,dis;
11 } p[SIZE];
12 int head[1005],pnum,dist[1005],dp[1005];
13 bool inq[1005];
14 queue <int> q;
15 void insert(int from, int to, int dis)
16 {
17 p[pnum].to = to;
18 p[pnum].next = head[from];
19 p[pnum].dis = dis;
20 head[from] = pnum++;
21 }
22 void SPFA(int vexnum)
23 {
24 int i,from,to,dis;
25 memset(inq, false, sizeof(inq));
26 for(i = 1; i <= vexnum; i++)
27 dist[i] = INF;
28 while(!q.empty())q.pop();
29 dist[2] = 0;
30 q.push(2);
31 while(!q.empty())
32 {
33 from = q.front();
34 q.pop();
35 inq[from] = false;
36 for(i = head[from]; i != -1; i = p[i].next)
37 {
38 to = p[i].to;
39 dis = p[i].dis;
40 if(dist[to] > dist[from] + dis)
41 {
42 dist[to] = dist[from] + dis;
43 if(!inq[to])
44 {
45 inq[to] = true;
46 q.push(to);
47 }
48 }
49 }
50 }
51 }
52
53 int dfs(int str)
54 {
55 int i,to,sum;
56 sum = 0;
57 if(dp[str]) return dp[str];
58 if(str == 2)return 1;
59 for(i = head[str]; i != -1; i = p[i].next){
60 to = p[i].to;
61 if(dist[to] < dist[str])
62 sum += dfs(to);
63 }
64 dp[str] = sum;
65 return sum;
66 }
67 int main()
68 {
69 int i,n,m,a,b,c;
70 // freopen("in.in","r",stdin);
71 while(scanf("%d",&n),n)
72 {
73 scanf("%d",&m);
74 memset(head, - 1, sizeof(head));
75 pnum = 0;
76 for(i = 0; i < m; i++)
77 {
78 scanf("%d%d%d",&a,&b,&c);
79 insert(a, b, c);
80 insert(b, a, c);
81 }
82 SPFA(n);
83 memset(dp, 0, sizeof(dp));
84 printf("%d\n",dfs(1));
85 }
86 return 0;
87 }