问题描述
给出一些Connections,即Connections类,找到一些能够将所有城市都连接起来并且花费最小的边。
如果说可以将所有城市都连接起来,则返回这个连接方法;不然的话返回一个空列表。
注意事项
返回cost最小的连接方法,如果cost相同就按照city1进行排序,如果city1也相同那么就按照city2进行排序。
样例
给出 connections = ["Acity","Bcity",1], ["Acity","Ccity",2], ["Bcity","Ccity",3]
返回 ["Acity","Bcity",1], ["Acity","Ccity",2]
思路
使用优先级队列存储所有的边,再用hash表存储每个节点的根。一开始设置每个节点的根节点为自己。
每次从优先级队列中取出最小的边,若这条边的两个节点的根节点相同,则继续取下一条边;
若根节点不同,则将其中一个根节点的根设置为另一个根节点,这条边同时加入最小生成树。
最后遍历所有的节点,查看所有节点的根节点是否一致,若存在不一致的根节点,说明存在多颗树,则返回一个空列表;
否则返回构成最小生成树的边的集合。
/**
* Definition for a Connection.
* class Connection {
* public:
* string city1, city2;
* int cost;
* Connection(string& city1, string& city2, int cost) {
* this->city1 = city1;
* this->city2 = city2;
* this->cost = cost;
* }
*/
class cmp{
public:
bool operator() (const Connection& a, const Connection& b) {
if (a.cost != b.cost)
return a.cost > b.cost;
else if (a.city1 != b.city1)
return a.city1 > b.city1;
else
return a.city2 > b.city2;
}
};
class Solution {
public:
/**
* @param connections given a list of connections include two cities and cost
* @return a list of connections from results
*/
vector<Connection> lowestCost(vector<Connection>& connections) {
// Write your code here
priority_queue<Connection, vector<Connection>, cmp> queue;
unordered_map<string, string> roots;
set<string> nodes;
vector<Connection> res;
for (int i=0; i<connections.size(); i++) {
string city1 = connections[i].city1;
string city2 = connections[i].city2;
queue.push(connections[i]);
roots[city1] = city1;
roots[city2] = city2;
}
while(!queue.empty()) {
Connection tmp = queue.top();
queue.pop();
string city1 = tmp.city1, city2 = tmp.city2,
root1 = findRoot(roots, city1), root2 = findRoot(roots, city2);
if (root1 == root2)
continue;
if (nodes.find(root1)!=nodes.end())
roots[root2] = root1;
else
roots[root1] = root2;
nodes.insert(root1); nodes.insert(root2);
res.push_back(tmp);
}
int count = 0;
unordered_map<string, string>::iterator iter = roots.begin();
string tt = findRoot(roots, (*iter).first);
for ( ++iter; iter != roots.end(); iter++ ){
if (findRoot(roots, (*iter).first) != tt){
count = -1;
break;
}
}
if (count == -1) {
return vector<Connection>();
} else {
return res;
}
}
string findRoot(unordered_map<string,string>& roots, string city) {
while (city != roots[city]) {
city = roots[city];
}
return city;
}
};