Skip to content
This repository was archived by the owner on Nov 29, 2020. It is now read-only.

Commit 9451073

Browse files
committed
TopologicalSort.cpp
1 parent e39a4ff commit 9451073

File tree

3 files changed

+105
-16
lines changed

3 files changed

+105
-16
lines changed

DFS.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,8 @@ std::ostream& operator<<(std::ostream& os, const DFSEdgeType& rhs) {
7676
}
7777
}
7878

79-
template <typename T>
80-
bool is_ancestor(umap<T, DFSInfo<T>>& ans, T u, T v) {
79+
template <typename T, typename VT>
80+
bool is_ancestor(VT& ans, T u, T v) {
8181
if (u == v)
8282
return true;
8383
DFSInfo<T>& info = ans[v];
@@ -88,50 +88,54 @@ bool is_ancestor(umap<T, DFSInfo<T>>& ans, T u, T v) {
8888
}
8989

9090
template <typename GT, typename T, typename VT, typename ET>
91-
void DFSVisit(GT& G, VT& ans, ET& edge_ans, T u, size_t& time) {
91+
void DFSVisit(GT& G, VT& ans, ET edge_ans, T u, size_t& time) {
9292
DFSInfo<T>& info = ans[u];
9393
info.set_color(gray, time);
9494
for (auto i = G.edges_from(u); !i.end(); i++) {
9595
T v = i.d();
9696
DFSInfo<T>& vinfo = ans[v];
9797
switch (vinfo.color) {
9898
case white:
99-
edge_ans[*i] = tree;
99+
if (edge_ans)
100+
(*edge_ans)[*i] = tree;
100101
vinfo.set_pi(u);
101102
DFSVisit(G, ans, edge_ans, v, time);
102103
break;
103104
case gray:
104-
edge_ans[*i] = back;
105+
if (edge_ans)
106+
(*edge_ans)[*i] = back;
105107
break;
106108
case black:
107-
if (is_ancestor(ans, u, v))
108-
edge_ans[*i] = forward;
109-
else
110-
edge_ans[*i] = cross;
109+
if (edge_ans) {
110+
if (is_ancestor(ans, u, v))
111+
(*edge_ans)[*i] = forward;
112+
else
113+
(*edge_ans)[*i] = cross;
114+
}
111115
break;
112116
}
113117
}
114118
info.set_color(black, time);
115119
}
116120

117121
template <typename GT, typename VT, typename ET>
118-
void DFS(GT& G, VT& ans, ET& edge_ans) {
122+
void DFS(GT& G, VT& ans, ET edge_ans) {
119123
using T = typename GT::vertix_type;
120124
for (auto i = G.V.begin(); i != G.V.end(); i++)
121125
ans[*i] = DFSInfo<T>();
122126
size_t time = 0;
123127
for (auto i = G.V.begin(); i != G.V.end(); i++)
124128
if (ans[*i].color == white)
125129
DFSVisit(G, ans, edge_ans, *i, time);
126-
if (!G.dir)
130+
if (!G.dir && edge_ans) {
131+
auto& ea = *edge_ans;
127132
for (auto i = G.all_edges(); !i.end(); i++)
128133
if (i.s() < i.d()) {
129134
Edge<T> j = (*i).reverse();
130-
if (edge_ans[*i] != edge_ans[j]) {
131-
edge_ans[j] = std::min(edge_ans[*i], edge_ans[j]);
132-
edge_ans[*i] = edge_ans[j];
133-
}
135+
if (ea[*i] != ea[j])
136+
ea[*i] = ea[j] = std::min(ea[*i], ea[j]);
134137
}
138+
}
135139
}
136140
#endif
137141

@@ -144,7 +148,7 @@ int main(int argc, char *argv[]) {
144148
random_graph(G, v, e);
145149
umap<size_t, DFSInfo<size_t>> inf;
146150
umap<Edge<size_t>, DFSEdgeType, EdgeHash<size_t>> edge_inf;
147-
DFS(G, inf, edge_inf);
151+
DFS(G, inf, &edge_inf);
148152
auto f1 = [inf](size_t v) mutable {
149153
DFSInfo<size_t>& i = inf[v];
150154
std::cout << " [";

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
| 22 | BFS.cpp | Print Path | 601 |
149149
| 22 | DFS.cpp | DFS | 604 |
150150
| 22 | DFS.cpp | DFS Visit | 604 |
151+
| 22 | TopologicalSort.cpp | Topological Sort | 613 |
151152

152153
# Supplementary Files
153154
* `utils.h`: Utils

TopologicalSort.cpp

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
//
2+
// algorithm - some algorithms in "Introduction to Algorithms", third edition
3+
// Copyright (C) 2018 lxylxy123456
4+
//
5+
// This program is free software: you can redistribute it and/or modify
6+
// it under the terms of the GNU Affero General Public License as
7+
// published by the Free Software Foundation, either version 3 of the
8+
// License, or (at your option) any later version.
9+
//
10+
// This program is distributed in the hope that it will be useful,
11+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
// GNU Affero General Public License for more details.
14+
//
15+
// You should have received a copy of the GNU Affero General Public License
16+
// along with this program. If not, see <https://www.gnu.org/licenses/>.
17+
//
18+
19+
#ifndef MAIN
20+
#define MAIN
21+
#define MAIN_TopologicalSort
22+
#endif
23+
24+
#ifndef FUNC_TopologicalSort
25+
#define FUNC_TopologicalSort
26+
27+
#include <deque>
28+
#include "utils.h"
29+
30+
#include "DFS.cpp"
31+
32+
template <typename GT, typename T, typename VT>
33+
void DFSVisit_TS(GT& G, VT& inf, std::deque<T>& ans, T u, size_t& time) {
34+
DFSInfo<T>& info = inf[u];
35+
info.set_color(gray, time);
36+
for (auto i = G.edges_from(u); !i.end(); i++) {
37+
T v = i.d();
38+
DFSInfo<T>& vinfo = inf[v];
39+
if (vinfo.color == white) {
40+
vinfo.set_pi(u);
41+
DFSVisit_TS(G, inf, ans, v, time);
42+
}
43+
}
44+
info.set_color(black, time);
45+
ans.push_front(u);
46+
}
47+
48+
template <typename GT, typename VT, typename T>
49+
void DFS_TS(GT& G, VT& inf, std::deque<T>& ans) {
50+
for (auto i = G.V.begin(); i != G.V.end(); i++)
51+
inf[*i] = DFSInfo<T>();
52+
size_t time = 0;
53+
for (auto i = G.V.begin(); i != G.V.end(); i++)
54+
if (inf[*i].color == white)
55+
DFSVisit_TS(G, inf, ans, *i, time);
56+
}
57+
58+
#endif
59+
60+
#ifdef MAIN_TopologicalSort
61+
int main(int argc, char *argv[]) {
62+
const size_t v = get_argv(argc, argv, 1, 5);
63+
const size_t e = get_argv(argc, argv, 2, 10);
64+
const bool dir = get_argv(argc, argv, 3, 0);
65+
GraphAdjList<size_t> G(dir);
66+
random_graph(G, v, e);
67+
umap<size_t, DFSInfo<size_t>> inf;
68+
std::deque<size_t> ans;
69+
DFS_TS(G, inf, ans);
70+
auto f1 = [inf](size_t v) mutable {
71+
DFSInfo<size_t>& i = inf[v];
72+
std::cout << " [label=\"" << v << "\\nd = " << i.d << "; f = " << i.f;
73+
if (i.pi_exist)
74+
std::cout << "; pi = " << i.pi;
75+
std::cout << "\"]";
76+
return true;
77+
};
78+
auto f2 = [](Edge<size_t> e) mutable {};
79+
graphviz(G, f1, f2);
80+
output_integers(ans);
81+
return 0;
82+
}
83+
#endif
84+

0 commit comments

Comments
 (0)