-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsol.cpp
More file actions
executable file
·168 lines (136 loc) · 3.04 KB
/
Copy pathsol.cpp
File metadata and controls
executable file
·168 lines (136 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <utility>
using namespace std;
struct Node; // Predefinition
struct Edge {
Node* source;
Node* target;
int weight;
Edge(){};
Edge(Node* s, Node* t, int w) {
source = s;
target = t;
weight = w;
}
bool operator<(const Edge& other) const {
return (weight > other.weight); // Watch out! Dirty priority queue hack :-) as it uses std::less as default comparison
}
};
struct Node {
int index;
string chars;
vector<Edge> edges;
bool in_tree = false;
};
void oneRun()
{
int n, length;
cin >> n >> length;
Node nodes[n];
/** Reading input and calculating weights */
// Read in all character sequences into the nodes.
for (int i = 0; i < n; i++) {
cin >> nodes[i].chars;
nodes[i].index = i;
}
// Construct the fully connected graph including all edge weights
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (i == j) continue; // Don't compare and connect from node X to node X
int diff = 0;
for (int k = 0; k < length; k++) {
if (nodes[i].chars.at(k) != nodes[j].chars.at(k)) diff++;
}
nodes[i].edges.emplace_back(Edge(&nodes[i], &nodes[j], diff));
}
}
int cost = 0; // For storing the sum weight of the MST
/** Construct the MST */
vector<pair<int, int>> connect; // To store the resulting edges
priority_queue<Edge> e_queue; // Edges to consider next using a priority queue
// Register starting node and add its edges to the queue
nodes[0].in_tree = true;
for (auto edge: nodes[0].edges) {
e_queue.push(edge);
}
Edge e;
while(not e_queue.empty()) {
// Pick and consume shortest edge in queue
e = e_queue.top();
e_queue.pop();
// Check if the target is already in the tree
if (e.target->in_tree) continue;
// If not...
e.target->in_tree = true; // Mark the target node of the edge as being in the MST
cost += e.weight; // Add the length of the edge to the cost sum
if (e.source->index > e.target->index) {
pair<int, int> ab (e.target->index, e.source->index); // Register edge in MST
connect.push_back(ab);
} else {
pair<int, int> ab (e.source->index, e.target->index); // Register edge in MST
connect.push_back(ab);
}
for (auto edge: e.target->edges) { // Update the queue with the newly reachable edges
e_queue.push(edge);
}
}
/** Finally return the answer */
cout << cost << endl;
for (auto c : connect) {
cout << get<0>(c) << " " << get<1>(c) << endl;
}
}
int main()
{
oneRun();
return 0;
}
/** Test cases
input:
1
4 2
AA
AT
TT
TC
output:
3
0 1
1 2
2 3
input:
1
4 1
A
A
G
T
output:
2
0 1
0 2
0 3
input:
1
5 6
GAACAG
AAAAAA
AACATA
GAAAAG
ATAAAT
output:
7
0 3
1 2
1 3
1 4
input:
1
3 1
A
A
A
*/