添加拓扑排序、最小生成树算法
This commit is contained in:
114
minimum-spanning-tree.cpp
Normal file
114
minimum-spanning-tree.cpp
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
class MST
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Minumum Spanning Tree
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
private:
|
||||||
|
vector<int> _pre; // pre-node
|
||||||
|
vector<int> _size; // size of node
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief : finding function of union set
|
||||||
|
* @param [x] : node index
|
||||||
|
* @retval : parent node
|
||||||
|
*/
|
||||||
|
int find(int x)
|
||||||
|
{
|
||||||
|
if (_pre[x] == x)
|
||||||
|
return x;
|
||||||
|
_pre[x] = find(_pre[x]);
|
||||||
|
return _pre[x];
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
/*!
|
||||||
|
* @brief : prim minimum spanning tree algorithm
|
||||||
|
* @param [num_nodes] : number of nodes
|
||||||
|
* @param [connections] : inter-node connection distance [start<72><74>end<6E><64>distance]
|
||||||
|
* @retval : minimum weighted-sum
|
||||||
|
*/
|
||||||
|
int prim(int num_nodes, vector<vector<int>>& connections)
|
||||||
|
{
|
||||||
|
vector<vector<pair<int, int>>> edges(n);
|
||||||
|
for (size_t i = 0; i < connections.size(); i++) {
|
||||||
|
int city_a = connections[i][0], city_b = connections[i][1];
|
||||||
|
int cost = connections[i][2];
|
||||||
|
edges[city_a].push_back(make_pair(city_b, cost));
|
||||||
|
edges[city_b].push_back(make_pair(city_a, cost));
|
||||||
|
}
|
||||||
|
set<int> intree; // set of visited node
|
||||||
|
vector<pair<int, int>> out_edges; // external edge
|
||||||
|
out_edges.push_back(make_pair(0, 0)); // target node
|
||||||
|
|
||||||
|
int ans = 0;
|
||||||
|
|
||||||
|
// iterate over all outward expanding edges until all nodes are visited
|
||||||
|
while (out_edges.size() != 0 && intree.size() != num_nodes)
|
||||||
|
{
|
||||||
|
// find the edge with minimal weight
|
||||||
|
vector<pair<int, int>>::iterator iter = min_element(out_edges.begin(), out_edges.end(), [&](pair<int, int>& elem1, pair<int, int>elem2)
|
||||||
|
{
|
||||||
|
return elem1.second < elem2.second;
|
||||||
|
|
||||||
|
});
|
||||||
|
pair<int, int> out_edge = *iter;
|
||||||
|
out_edges.erase(iter);
|
||||||
|
|
||||||
|
// add unvisited node
|
||||||
|
if (intree.find(out_edge.first) == intree.end())
|
||||||
|
{
|
||||||
|
intree.insert(out_edge.first);
|
||||||
|
ans += out_edge.second;
|
||||||
|
for (pair<int, int> edge : edges[out_edge.first])
|
||||||
|
{
|
||||||
|
out_edges.push_back(make_pair(edge.first, edge.second));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intree.size() != num_nodes)
|
||||||
|
return -1; // not exist if two nodes is not connected
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief : Kruskal MST algorithm
|
||||||
|
* @param [num_nodes] : Number of nodes
|
||||||
|
* @param [connections] : Inter-node connection distance [start<72><74>end<6E><64>distance]
|
||||||
|
* @retval : Minimum weighted-sum
|
||||||
|
*/
|
||||||
|
int kruskal(int numNodes, vector<vector<int>>& connections)
|
||||||
|
_pre.resize(numNodes), _size.resize(numNodes, 1);
|
||||||
|
iota(_pre.begin(), _pre.end(), 0);
|
||||||
|
|
||||||
|
// sort with the distance
|
||||||
|
sort(connections.begin(), connections.end(), [&](vector<int>& elem1, vector<int>& elem2) {
|
||||||
|
return elem1.at(2) < elem2.at(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
int ans = 0; // minimum weighted-sum
|
||||||
|
int edge_count = 0; // number of visited nodes
|
||||||
|
for (size_t i = 0; i < connections.size(); i++) {
|
||||||
|
int x = find(connections[i][0]), y = find(connections[i][1]);
|
||||||
|
|
||||||
|
// Union find set
|
||||||
|
if (x != y) {
|
||||||
|
if (_size[x] > _size[y]) {
|
||||||
|
swap(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
_pre[x] = y;
|
||||||
|
_size[y] += _size[x];
|
||||||
|
ans += connections[i][2];
|
||||||
|
edge_count++;
|
||||||
|
if (edge_count == numNodes - 1) {
|
||||||
|
return ans;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1; // not exist if two nodes is not connected
|
||||||
|
}
|
||||||
|
};
|
72
topological-sorting.cpp
Normal file
72
topological-sorting.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
class Solution
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
enum class STATUS
|
||||||
|
{
|
||||||
|
UN_VISITED,
|
||||||
|
IN_SEARCHING,
|
||||||
|
FINISHED
|
||||||
|
};
|
||||||
|
|
||||||
|
vector<vector<int>> edges;
|
||||||
|
vector<Status> visited;
|
||||||
|
vector<int> sequence;
|
||||||
|
|
||||||
|
bool find_cycle = false; // cycle
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief deep first search
|
||||||
|
* @param[in] node index
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void deepFirstSearch(int node)
|
||||||
|
{
|
||||||
|
visited[node] = Status::SEARCHING;
|
||||||
|
for (int neighbor : edges[node]) {
|
||||||
|
if (visited[neighbor] == Status::UNVISITED) {
|
||||||
|
deepFirstSearch(neighbor);
|
||||||
|
if (find_cycle) {
|
||||||
|
return; // unsolvable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (visited[neighbor] == Status::SEARCHING) {
|
||||||
|
find_cycle = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visited[node] = Status::FINISH;
|
||||||
|
sequence.push_back(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief topological sequence
|
||||||
|
* @param[in] number of nodes
|
||||||
|
* @param[in] node connection
|
||||||
|
* @retval sequence
|
||||||
|
*/
|
||||||
|
vector<int> findTopologicalOrder(int numNodes, vector<vector<int>>& linkage)
|
||||||
|
{
|
||||||
|
edges.resize(numNodes);
|
||||||
|
visited.resize(numNodes, Status::UNVISITED);
|
||||||
|
|
||||||
|
// generate adjacency list
|
||||||
|
for (const auto& info : linkage) {
|
||||||
|
edges[info[1]].push_back(info[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// deep first search to determine the topological sequence
|
||||||
|
for (int i = 0; i < numNodes && !find_cycle; ++i) {
|
||||||
|
if (visited[i] == Status::UNVISITED) {
|
||||||
|
deepFirstSearch(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (find_cycle) {
|
||||||
|
return vector<int>(); // unsolvable for cycle
|
||||||
|
}
|
||||||
|
|
||||||
|
reverse(sequence.begin(), sequence.end());
|
||||||
|
return sequence;
|
||||||
|
}
|
||||||
|
};
|
Reference in New Issue
Block a user