问题:
http://acm.pku.edu.cn/JudgeOnline/problem?id=1511思路:
第一次写SPFA,其实是在discuss里总是看到SPFA这东东,于是今天就好奇地查了下,原来是求最短路径的快速算法
除了SPFA,这题还学到了:
1. 如何静态地建立邻接表,大开眼界,原来邻接表还可以这么建的,膜拜...
2. 求一个顶点到其他各个顶点的最短路径,显然,是单源最短路径
求其他各个顶点到某一个特定顶点的最短路径,其实也是单源最短路径,只要将原始有向图逆向即可
参考:
http://www.cnblogs.com/zhangjinglei/archive/0001/01/01/1532389.html代码:
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #define MAX_N 1000005
5 #define INF 0x7FFFFFFF
6 struct Edge { /* build adj-list statically */
7 int to;
8 int cost;
9 int next;
10 };
11 struct Edge edges[MAX_N], op_edges[MAX_N];
12 int assist[MAX_N], op_assist[MAX_N];
13 int mark[MAX_N], d[MAX_N];
14 int queue[MAX_N];
15 int P, Q;
16
17 void
18 init()
19 {
20 int i, f, t, c;
21 scanf("%d %d", &P, &Q);
22 memset(assist, -1, sizeof(assist));
23 memset(op_assist, -1, sizeof(op_assist));
24 for(i=0; i<Q; i++) {
25 scanf("%d %d %d", &f, &t, &c);
26 edges[i].to = t;
27 edges[i].cost = c;
28 edges[i].next = assist[f];
29 assist[f] = i;
30 /* reverse graph */
31 op_edges[i].to = f;
32 op_edges[i].cost = c;
33 op_edges[i].next = op_assist[t];
34 op_assist[t] = i;
35 }
36 }
37
38 long long
39 spfa(struct Edge *e, int *ass, int begin)
40 {
41 int i, j, head, tail, cur;
42 memset(mark, 0, sizeof(mark));
43 for(i=1; i<=P; i++)
44 d[i] = INF;
45 head = -1;
46 tail = 0;
47 d[begin] = 0;
48 mark[begin] = 1;
49 queue[tail] = begin;
50 while(head < tail) {
51 ++head;
52 cur = queue[head];
53 mark[cur] = 0;
54 for(j=ass[cur]; j!=-1; j=e[j].next) {
55 if(d[e[j].to] > d[cur]+e[j].cost) {
56 d[e[j].to] = d[cur] + e[j].cost;
57 if(!mark[e[j].to]) {
58 ++tail;
59 queue[tail] = e[j].to;
60 mark[e[j].to] = 1;
61 }
62 }
63 }
64 }
65 long long rt = 0;
66 for(i=1; i<=P; i++)
67 rt += d[i];
68 return rt;
69 }
70
71 int
72 main(int argc, char **argv)
73 {
74 int tests;
75 scanf("%d", &tests);
76 while(tests--) {
77 init();
78 printf("%lld\n", spfa(edges, assist, 1)+spfa(op_edges, op_assist, 1));
79 }
80 }