ACM/ICPC 之 最短路-SPFA+正逆邻接表(POJ1511(ZOJ2008))

求单源最短路到其余各点,然后返回源点的总最短路长,以构造邻接表的方法不同分为两种解法。



POJ1511(ZOJ2008)-Invitation Cards

  改变构造邻接表的方法后,分为两种解法

解法一:

 1 //POJ1511-ZOJ2008
 2 //Time:7766Ms    Memory:99112K
 3 //求从1处到各点后再返回1处的最短总路长
 4 //需要构造邻接表和逆邻接表
 5 //构造方法1:vector构造邻接表
 6 //SPFA+邻接表
 7 #include<iostream>
 8 #include<cstring>
 9 #include<cstdio>
10 #include<vector>
11 #include<queue>
12 using namespace std;
13
14 #define MAX 1000005
15 #define INF 0x3f3f3f3f
16
17 struct Edge {
18     int u, w;
19     Edge(int uu, int ww) :u(uu), w(ww) {}
20 };
21
22 vector<Edge> e1[MAX], e2[MAX];    //邻接表-逆邻接表
23
24 int n, m;
25 int d[MAX];
26 long long sum;
27 bool v[MAX];
28
29 void SPFA(int x, vector<Edge> e[MAX])
30 {
31     memset(d, INF, sizeof(d));
32     memset(v, false, sizeof(v));
33     queue<int> q;
34     q.push(x);
35     d[x] = 0;
36     while (!q.empty()){
37         int cur = q.front();
38         q.pop();
39         v[cur] = false;
40         for (int i = 0; i < e[cur].size(); i++)
41         {
42             int u = e[cur][i].u;
43             if (d[u] > d[cur] + e[cur][i].w)
44             {
45                 d[u] = d[cur] + e[cur][i].w;
46                 if (!v[u]) { q.push(u); v[u] = true; }
47             }
48         }
49     }
50     for (int i = 2; i <= n; i++)
51         sum += d[i];
52 }
53
54 int main()
55 {
56     int T;
57     scanf("%d", &T);
58     while (T--) {
59         sum = 0;
60         memset(e1, 0, sizeof(e1));
61         memset(e2, 0, sizeof(e2));
62         scanf("%d%d", &n, &m);
63         while (m--) {
64             int u, v, w;
65             scanf("%d%d%d", &u, &v, &w);
66             e1[u].push_back(Edge(v, w));    //正向
67             e2[v].push_back(Edge(u, w));    //逆向
68         }
69
70         SPFA(1, e1);
71         SPFA(1, e2);
72         printf("%lld\n", sum);
73     }
74
75     return 0;
76 }

解法二:

 1 //POJ1511-ZOJ2008
 2 //Time:2000Ms    Memory:36424K
 3 //求从1处到各点后再返回1处的最短总路长
 4 //需要构造邻接表和逆邻接表
 5 //构造方法2:偏序关系构造邻接表
 6 //SPFA+邻接表
 7 #include<iostream>
 8 #include<cstring>
 9 #include<cstdio>
10 #include<vector>
11 #include<queue>
12 using namespace std;
13
14 #define MAX 1000005
15 #define INF 0x3f3f3f3f
16
17 struct Edge {
18     int u, w, next;
19     Edge() {}
20     Edge(int uu, int ww, int nn) :u(uu), w(ww), next(nn) {}
21 }e1[MAX], e2[MAX];    //邻接表-逆邻接表
22
23 int h1[MAX], h2[MAX];    //正表表头-逆表表头
24 int n, m;
25 int d[MAX];
26 long long sum;
27 bool v[MAX];
28
29 void SPFA(int x, Edge e[MAX], int h[MAX])
30 {
31     memset(d, INF, sizeof(d));
32     memset(v, false, sizeof(v));
33     queue<int> q;
34     q.push(x);
35     d[x] = 0;
36     while (!q.empty()){
37         int cur = q.front();
38         q.pop();
39         v[cur] = false;
40         for (int i = h[cur]; i != -1; i = e[i].next)
41         {
42             int u = e[i].u;
43             int w = e[i].w;
44             if (d[u] > d[cur] + w)
45             {
46                 d[u] = d[cur] + w;
47                 if (!v[u]) { q.push(u); v[u] = true; }
48             }
49         }
50     }
51     for (int i = 2; i <= n; i++)
52         sum += d[i];
53 }
54
55 int main()
56 {
57     int T;
58     scanf("%d", &T);
59     while (T--) {
60         sum = 0;
61         memset(e1, 0, sizeof(e1));
62         memset(e2, 0, sizeof(e2));
63         memset(h1, -1, sizeof(h1));
64         memset(h2, -1, sizeof(h2));
65         scanf("%d%d", &n, &m);
66         for (int i = 0; i < m; i++) {
67             int u, v, w;
68             scanf("%d%d%d", &u, &v, &w);
69             e1[i] = Edge(v, w, h1[u]);
70             e2[i] = Edge(u, w, h2[v]);
71             h1[u] = h2[v] = i;
72         }
73
74         SPFA(1, e1, h1);
75         SPFA(1, e2, h2);
76         printf("%lld\n", sum);
77     }
78
79     return 0;
80 }
时间: 2024-08-27 19:14:20

ACM/ICPC 之 最短路-SPFA+正逆邻接表(POJ1511(ZOJ2008))的相关文章

ACM:最短路,dijkstra,邻接表的建立,使用邻接表跟优先队列的dijkstra,Bellman-Ford,Floyd。。

(一)dijkstra,邻接矩阵 所有边权均为正,不管有没有环,求单个源点出发,到所有节点的最短路.该方法同时适用于有向图和无向图. #include <iostream> #include <string> #include <stack> using namespace std; const int MAXN = 1000; const int INF = 100000000; int n, m; int maze[MAXN][MAXN], vis[MAXN], d

ACM/ICPC 之 最短路-Floyd+SPFA(BFS)+DP(ZOJ1232)

这是一道非常好的题目,融合了很多知识点. ZOJ1232-Adventrue of Super Mario 这一题折磨我挺长时间的,不过最后做出来非常开心啊,哇咔咔咔 题意就不累述了,注释有写,难点在于状态转移方程的确立和SPFA的过程 1 //最短路:Floyd+SPFA(BFS)+DP 2 //Time:20Ms Memory:336K 3 //题目很好,数据较弱,网上部分代码有些问题却能够A掉 4 //题意:超级马里奥要从A+B处背着公主以最短路程到达1处,其中1-A是村庄,剩下的是城堡

2016 ACM/ICPC Asia Regional Qingdao Online 1001/HDU5878 打表二分

I Count Two Three Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 782    Accepted Submission(s): 406 Problem Description I will show you the most popular board game in the Shanghai Ingress Resis

ACM/ICPC 之 SPFA范例两道(POJ3268-POJ3259)

两道以SPFA算法求解的最短路问题,比较水,第二题需要掌握如何判断负权值回路. POJ3268-Silver Cow Party //计算正逆最短路径之和的最大值 //Time:32Ms Memory:360K #include<iostream> #include<cstring> #include<cstdio> #include<queue> #include<algorithm> using namespace std; #define

2017 ACM/ICPC Asia Regional Shenyang Online spfa+最长路

transaction transaction transaction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)Total Submission(s): 1496    Accepted Submission(s): 723 Problem Description Kelukin is a businessman. Every day, he travels arou

ACM/ICPC 之 SPFA练习两道(ZOJ3088-ZOJ3103)

两道题都需要进行双向SPFA,比范例复杂,代码也较长,其中第二题应该可以用DFS或者BFS做,如果用DFS可能需要的剪枝较多. ZOJ3088-Easter Holydays //利用SPFA找出下降最长路径和上升最短路径,输出最大的比值和回路路径 //Time:0Ms Memory:328K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include&

ACM/ICPC 之 DFS+SPFA-贪心+最短路(POJ2679)

//POJ2679 //DFS+SPFA+邻接表 //只能走每个点费用最小的边,相同则需保证距离最短 //求最小费用及最短距离 //Time:47Ms Memory:900K #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; #define MAXN 1105 #define

hdu 5016 点分治(2014 ACM/ICPC Asia Regional Xi&#39;an Online)

Mart Master II Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 675    Accepted Submission(s): 237 Problem Description Trader Dogy lives in city S, which consists of n districts. There are n - 1

《ACM/ICPC 算法训练教程》读书笔记一之数据结构(堆)

书籍简评:<ACM/ICPC 算法训练教程>这本书是余立功主编的,代码来自南京理工大学ACM集训队代码库,所以小编看过之后发现确实很实用,适合集训的时候刷题啊~~,当时是听了集训队final的意见买的,感觉还是不错滴. 相对于其他ACM书籍来说,当然如书名所言,这是一本算法训练书,有着大量的算法实战题目和代码,尽管小编还是发现了些许错误= =,有部分注释的语序习惯也有点不太合我的胃口.实战题目较多是比较水的题,但也正因此才能帮助不少新手入门,个人认为还是一本不错的算法书,当然自学还是需要下不少