DP真的是相当相当地强大啊...
dp[i][1]表示到达点i最短的路有多少条,dp[i][2]表示次短的条数
dist[i][1]表示到达点i最短路的长度,dist[i][2].........................
初始化为dist[st][1]=0 其他为max_int dp[st][1]=1 其他为0
用v去松驰u时有四种情况 (设当前dist[v][cas])
情况1:dist[v][cas]+w(v,u)<dist[u][1],找到一个更短的距离,则把原来最短的距离作为次短的距离,同时更新最短的.即
dist[u][2]=dist[u][1]
dist[u][1]=dist[v][cas]+w(v,u);
dp[u][2]=dp[u][1]
dp[u][1]=dp[v][cas],
把Node(dist[u][1],u,1)和Node(dist[u][2],u,2)放入队列
情况2:dist[v][cas]+w(v,u)==dist[u][1],找到一条新的相同距离的最短路,则dp[u][1]+=dp[v][cas],其他不用更新,也不入队
情况3:dist[v][cas]+w(v,u)<dist[u][2],不可以更新最短距离,但可以更新次短的,则更新dist[u][2]和dp[u][2]
dist[u][2]=dist[v][cas]+w(v,u);
dp[u][2]=dp[v][cas];
把Node(dist[u][2],u,2)放入队列
情况4:dist[v][cas]+w(v,u)==dist[u][2] 找到一条新的相同距离的次短路,则dp[u][2]+=dp[v][cas],其他不更新。
代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #define MAX_N 1001
5 #define INF 0x7FFFFFFF
6 int d[MAX_N][2], in[MAX_N][2], cnt[MAX_N][2];
7 int n, m, from, to;
8 struct Node {
9 int target, cost;
10 struct Node *next;
11 };
12 struct Node *nodes[MAX_N]; /* adj list: there may be different roads between city A and city B */
13
14 void
15 init()
16 {
17 int i, f, t, c;
18 struct Node *fresh;
19 memset(nodes, 0, sizeof(nodes));
20 scanf("%d %d", &n, &m);
21 for(i=0; i<m; i++) {
22 scanf("%d %d %d", &f, &t, &c);
23 fresh = (struct Node *)malloc(sizeof(struct Node));
24 fresh->target = t;
25 fresh->cost = c;
26 fresh->next = nodes[f];
27 nodes[f] = fresh;
28 }
29 scanf("%d %d", &from, &to);
30 }
31
32 void
33 dijkstra()
34 {
35 int i, j, k, p, min, v, cur;
36 struct Node *tmp;
37 memset(in, 0, sizeof(in));
38 memset(cnt, 0, sizeof(cnt));
39 /* d[i][0]: minimum path, d[i][1]: second minimum path */
40 for(i=1; i<=n; i++)
41 d[i][0] = d[i][1] = INF;
42 d[from][0] = 0;
43 cnt[from][0] = 1;
44 for(i=1; i<=2*n; i++) { /* each vertex has two chance to relax */
45 min = INF;
46 p = -1;
47 for(j=1; j<=n; j++) {
48 if(!in[j][0] && d[j][0]<min) {
49 min = d[j][0];
50 p = j;
51 k = 0;
52 } else if(!in[j][1] && d[j][1]<min) {
53 min = d[j][1];
54 p = j;
55 k = 1;
56 }
57 }
58 if(p == -1)
59 break;
60 in[p][k] = 1;
61 tmp = nodes[p];
62 while(tmp != NULL) { /* Relax */
63 v = tmp->target;
64 cur = d[p][k] + tmp->cost;
65 if(cur < d[v][0]) {
66 d[v][1] = d[v][0];
67 cnt[v][1] = cnt[v][0];
68 d[v][0] = cur;
69 cnt[v][0] = cnt[p][k];
70 } else if(cur == d[v][0]) {
71 cnt[v][0] += cnt[p][k];
72 } else if(cur < d[v][1]) {
73 d[v][1] = cur;
74 cnt[v][1] = cnt[p][k];
75 } else if(cur == d[v][1]) {
76 cnt[v][1] += cnt[p][k];
77 }
78 tmp = tmp->next;
79 }
80 }
81 }
82
83 int
84 main(int argc, char **argv)
85 {
86 int tests, rt;
87 scanf("%d", &tests);
88 while(tests--) {
89 init();
90 dijkstra();
91 rt = cnt[to][0];
92 if(d[to][0]+1 == d[to][1])
93 rt += cnt[to][1];
94 printf("%d\n", rt);
95 }
96 }