22#include < fstream>
33#include < sstream>
44#include < string>
5- #include < utility>
6- #include < set>
7- #include < map>
85#include < vector>
96#include < algorithm>
10- #include < tuple>
7+ #include < map>
8+ #include < set>
119
12- using namespace std ;
10+ typedef std::string Node ;
1311
14- class Graph {
15-
16- typedef pair<string, string> Edge; // calling Edge
17- typedef pair< int , Edge> WEdge; // Weighted edge
12+ struct Connection {
13+ Node src;
14+ Node dst;
15+ };
1816
17+ typedef std::pair<int , Connection> Edge;
1918
19+ bool comparePtrToWeight (Edge& a, Edge& b)
20+ {
21+ return (a.first < b.first );
22+ }
2023
24+ class Graph {
2125private:
22- set<string> nodes; // Keep track of unique Nodes in graph
23- vector<WEdge> graph;
24- map<string, string> disjoint; // map for disjoints
25-
26- const string& add_node (string node) {
27- pair<set<string>::iterator,bool > insert_ret;
28- insert_ret = nodes.insert (node);
29-
30- const string& retVal = *insert_ret.first ;
31-
32- disjoint.insert (pair<string, string>(node, node));
33-
34- return retVal;
35- }
36-
37- string& mst_find (string& index) {
38- if (index != disjoint[index]) {
39- disjoint[index] = mst_find (disjoint[index]);
40- }
41-
42- return disjoint[index];
43- }
44-
26+ std::set<Node> nodes;
27+ std::vector<Edge> graph;
28+ std::map<Node, Node> tree;
4529public:
46- void add_edge (string start, string end, int weight) {
47- (void ) add_node (start);
48- (void ) add_node (end);
30+ const Node& addNode (Node& node);
31+ Node& findNode (Node& node);
32+ void addEdge (Edge& edge);
33+ std::pair<std::vector<Edge>, int > MST ();
34+ };
4935
50- graph.push_back (WEdge (weight, Edge (start, end)));
36+ const Node& Graph::addNode (Node& node)
37+ {
38+ std::pair<std::set<Node>::iterator, bool > insert_result = nodes.insert (node);
39+ const Node& result = *insert_result.first ;
40+ this ->tree .insert (std::pair<Node, Node>(node, node));
41+ return result;
42+ }
43+
44+ Node& Graph::findNode (Node& node)
45+ {
46+ if (node != this ->tree [node])
47+ {
48+ this ->tree [node] = findNode (this ->tree [node]);
5149 }
50+ return this ->tree [node];
51+ }
5252
53- int mst () {
54- int total_w = 0 ;
55-
56- sort (graph.begin (), graph.end ());
57- vector<tuple<int , string, string>> out;
58-
59- vector<WEdge>::iterator it;
60- for (it = graph.begin (); it != graph.end (); ++it) {
61- string start = it->second .first ;
62- string end = it->second .second ;
53+ void Graph::addEdge (Edge& edge)
54+ {
55+ addNode (edge.second .src );
56+ addNode (edge.second .dst );
6357
64- string& set_start = mst_find (start);
65- string& set_end = mst_find (end);
66-
67- if (start == " GP" && end.substr (0 , 2 ) == " Ch" )
68- {
69- set_start = mst_find (set_start);
70- set_end = mst_find (set_end);
71- disjoint[set_end] = set_start;
72-
73- out.push_back (make_tuple (it->first , start, end));
74- total_w += it->first ;
75- break ;
76- }
58+ this ->graph .push_back (edge);
59+ }
7760
78- }
7961
80- for (it = graph.begin (); it != graph.end (); ++it) {
81- string start = it->second .first ;
82- string end = it->second .second ;
62+ std::pair<std::vector<Edge>, int > Graph::MST ()
63+ {
64+ std::vector<Edge> min_spanning_tree;
65+ int total_cost = 0 ;
8366
84- string& set_start = mst_find (start);
85- string& set_end = mst_find ( end);
67+ // Sort the edges of the graph.
68+ std::sort ( this -> graph . begin (), this -> graph . end (), comparePtrToWeight );
8669
87- if (start == " GP" && end == " Hipp" )
88- {
89- set_start = mst_find (set_start);
90- set_end = mst_find (set_end);
91- disjoint[set_end] = set_start;
70+ std::vector<Edge>::iterator it;
71+ // Constrain 2 and 5
72+ for (it = graph.begin (); it != graph.end (); ++it)
73+ {
74+ Node start_node = it->second .src ;
75+ Node end_node = it->second .dst ;
9276
93- out.push_back (make_tuple (it->first , start, end));
94- total_w += it->first ;
95- break ;
96- }
77+ Node& src = findNode (start_node);
78+ Node& dst = findNode (end_node);
9779
80+ if (" GP" == src && " Hipp" == dst)
81+ {
82+ src = findNode (src);
83+ dst = findNode (dst);
84+ tree[dst] = src;
85+
86+ Connection e = { src, dst };
87+ min_spanning_tree.push_back (std::make_pair (it->first , e));
88+ total_cost += it->first ;
89+ break ;
9890 }
91+ }
9992
93+ // Constrain 3 and 4
94+ for (it = graph.begin (); it != graph.end (); ++it)
95+ {
96+ Node start_node = it->second .src ;
97+ Node end_node = it->second .dst ;
10098
101- for (it = graph.begin (); it != graph.end (); ++it) {
102- string start = it->second .first ;
103- string end = it->second .second ;
104-
105- string& set_start = mst_find (start);
106- string& set_end = mst_find (end);
107-
108- if (start == " Hipp" && end.substr (0 ,3 ) == " Bas" )
109- {
110- continue ;
111- }
112-
113- if ( end == " Hipp" && start.substr (0 ,3 ) == " Bas" )
114- {
115- continue ;
116- }
117-
118- if ( end.substr (0 , 2 ) == " Hp" && start.substr (0 , 2 ) == " Hp" )
119- {
120- continue ;
121- }
122-
99+ Node& src = findNode (start_node);
100+ Node& dst = findNode (end_node);
123101
124- if (set_start != set_end) {
125- // cout << start << " " << end << " " << it->first<< endl;
126- out.push_back (make_tuple (it->first , start, end));
127- total_w += it->first ;
102+ if ((" GP" == src && " Ch" == dst.substr (0 , 2 )) || (" GP" == dst && " Ch" == src.substr (0 , 2 )))
103+ {
104+ src = findNode (src);
105+ dst = findNode (dst);
106+ tree[dst] = src;
107+
108+ Connection e = { src, dst };
109+ min_spanning_tree.push_back (std::make_pair (it->first , e));
110+ total_cost += it->first ;
111+ break ;
112+ }
113+ }
128114
129- set_start = mst_find (set_start);
130- set_end = mst_find (set_end);
131- disjoint[set_end] = set_start;
115+ for (it = graph.begin (); it != graph.end (); ++it)
116+ {
117+ Node start_node = it->second .src ;
118+ Node end_node = it->second .dst ;
132119
133- }
120+ Node& src = findNode (start_node);
121+ Node& dst = findNode (end_node);
134122
123+ if (" Hp" == src.substr (0 , 2 ) && " Hp" == dst.substr (0 , 2 )) // Constrain 7
124+ {
125+ continue ;
135126 }
136- sort (out.begin (), out.end ());
137- for (tuple<int , string, string> t : out)
127+ else if ((" Hipp" == src && " Bas" == dst.substr (0 , 3 )) || (" Bas" == src.substr (0 , 3 ) && " Hipp" == dst)) // Constrain 6
138128 {
139- cout << get< 1 >(t) << " " << get< 2 >(t) << " " << get< 0 >(t) << endl ;
129+ continue ;
140130 }
141-
142- cout << total_w << endl;
143-
144- return 0 ;
145- }
146-
147- // Print out graph edges with weights
148- friend ostream& operator << (ostream& outs, Graph& graph) {
149- typename vector<WEdge>::iterator it;
150-
151- for (it = graph.graph .begin (); it != graph.graph .end (); ++it) {
152- outs << it->second .first << " --" << it->first << " -- " << it->second .second << endl;
131+ else
132+ {
133+ src = findNode (src);
134+ dst = findNode (dst);
135+ tree[dst] = src;
136+
137+ Connection e = { src, dst };
138+ min_spanning_tree.push_back (std::make_pair (it->first , e));
139+ total_cost += it->first ;
140+ break ;
153141 }
154-
155- return outs;
156142 }
157- };
158-
159- class City : public Graph {};
160143
161- int main () {
144+ sort (min_spanning_tree. begin (), min_spanning_tree. end (), comparePtrToWeight);
162145
163- City deneme;
146+ return std::pair<std::vector<Edge>, int >(min_spanning_tree, total_cost);
147+ }
164148
165- string line;
166- string line_param;
167- vector<string> line_parse;
168- // stringstream weight_converter;
169- string weight_converter;
149+ int main ()
150+ {
151+ // Create an empty graph.
152+ Graph g;
170153
171- ifstream city_plan (" city_plan.txt" );
154+ // Read from file
155+ std::string file_name;
156+ std::string line;
157+ std::string str;
158+ std::vector<std::string> params;
172159
173- if (city_plan.is_open ()) { // Sanity check
174- // Parsing file into graph
175- while (getline (city_plan, line)) {
176- line_parse.clear ();
160+ std::cin >> file_name;
161+ std::ifstream city_plan (file_name);
177162
178- istringstream parsing_line (line);
179- while (getline (parsing_line, line_param, ' ,' )) {
180- line_parse.push_back (line_param);
163+ // Fill the graph.
164+ if (city_plan.is_open ())
165+ {
166+ while (std::getline (city_plan, line))
167+ {
168+ params.clear ();
169+ std::istringstream parser (line);
170+ while (getline (parser, str, ' ,' ))
171+ {
172+ params.push_back (str);
181173 }
182-
183- if (3 == line_parse.size ()) { // Sanity check
184- // weight_converter << line_parse[2];
185-
186- weight_converter = line_parse[2 ];
187- int weight = std::stoi (weight_converter);
188- deneme.add_edge (line_parse[0 ], line_parse[1 ], weight);
189-
190- /* int weight = 0;
191- weight_converter >> weight;
192- deneme.add_edge(line_parse[0], line_parse[1], weight);*/
174+ if (3 == params.size ())
175+ {
176+ Connection c = { params[0 ], params[1 ] };
177+ std::pair<int , Connection> e = std::make_pair (std::stoi (params[2 ]), c);
178+ g.addEdge (e);
193179 }
194180 }
195-
196181 city_plan.close ();
197182 }
198183
199- deneme.mst ();
184+ // Run the Minimum Spanning Tree algorithm.
185+ std::pair<std::vector<Edge>, int > min_spanning_tree = g.MST ();
186+
187+ // Print edges
188+ for (Edge& e : min_spanning_tree.first )
189+ {
190+ std::cout << e.second .src << " " << e.second .dst << " " << e.first << std::endl;
191+ }
192+
193+ // Print total cost
194+ std::cout << min_spanning_tree.second << std::endl;
200195
201196 return 0 ;
202- }
197+ }
0 commit comments