前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 1135. 最低成本联通所有城市(最小生成树+排序+并查集)

LeetCode 1135. 最低成本联通所有城市(最小生成树+排序+并查集)

作者头像
Michael阿明
发布2021-02-19 10:49:56
2.2K0
发布2021-02-19 10:49:56
举报
文章被收录于专栏:Michael阿明学习之路

文章目录

1. 题目

想象一下你是个城市基建规划者,地图上有 N 座城市,它们按以 1 到 N 的次序编号。

给你一些可连接的选项 conections,其中每个选项 conections[i] = [city1, city2, cost] 表示将城市 city1 和城市 city2 连接所要的成本。(连接是双向的,也就是说城市 city1 和城市 city2 相连也同样意味着城市 city2 和城市 city1 相连)。

返回使得每对城市间都存在将它们连接在一起的连通路径(可能长度为 1 的)最小成本。 该最小成本应该是所用全部连接代价的综合。如果根据已知条件无法完成该项任务,则请你返回 -1。

示例 1:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
输入:N = 3, conections = [[1,2,5],[1,3,6],[2,3,1]]
输出:6
解释:
选出任意 2 条边都可以连接所有城市,我们从中选取成本最小的 2 条。

示例 2:

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
输入:N = 4, conections = [[1,2,3],[3,4,4]]
输出:-1
解释: 
即使连通所有的边,也无法连接所有城市。
 
提示:
1 <= N <= 10000
1 <= conections.length <= 10000
1 <= conections[i][0], conections[i][1] <= N
0 <= conections[i][2] <= 10^5
conections[i][0] != conections[i][1]

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/connecting-cities-with-minimum-cost 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2. 解题

图Graph–最小生成树

1. Kruskal

  • 将边的权值排序,小的先遍历,用并查集检查两个顶点是否合并了,没有合并则将该边加入生成树
  • 也可以使用优先队列实现(相当于排序)
代码语言:javascript
复制
class dsu
{
	vector<int> f;
public:
	dsu(int n)
	{
		f.resize(n);
		for(int i = 0; i < n; ++i)
			f[i] = i;
	}
	void merge(int a, int b)
	{
		int fa = find(a);
		int fb = find(b);
		f[fa] = fb;
	}
	int find(int a)
	{
		int origin = a;
		while(a != f[a])
		{
			a = f[a];
		}
		return f[origin] = f[a];
	}
};

class Solution {
public:
    int minimumCost(int N, vector<vector<int>>& connections) {
    	dsu u(N+1);
    	sort(connections.begin(), connections.end(),[&](auto a, auto b){
    		return a[2] < b[2];//距离短的边优先
    	});
    	int edge = 0, p1, p2, dis, total = 0;
    	for(int i = 0; i < connections.size(); ++i)
    	{
    		p1 = connections[i][0];
    		p2 = connections[i][1];
    		dis = connections[i][2];
    		if(u.find(p1) != u.find(p2))//两个还未链接
    		{
    			u.merge(p1,p2);
    			edge++;
    			total += dis;
    		}
    		if(edge == N-1)
    			break;
    	}
    	return edge==N-1 ? total : -1;
    }
};

1504 ms 158.6 MB

2. prim

  • 把一个初始顶点的所有边加入优先队列
  • 取出最短的边,把这条边的另一个顶点相关的边加入队列
  • 再取出最小的边,重复下去,直到所有顶点加入过了
代码语言:javascript
复制
struct cmp
{
	bool operator()(const pair<int,int>& a, const pair<int,int>& b) const
	{
		return a.second > b.second;//小顶堆, 距离小的优先
	}
};
class Solution {
public:
    int minimumCost(int N, vector<vector<int>>& connections) {
		vector<bool> vis(N+1, false);
    	vector<vector<pair<int,int>>> edges(N+1,vector<pair<int,int>>());
    	for(auto& c : connections)
        {
            edges[c[0]].push_back({c[1],c[2]});
            edges[c[1]].push_back({c[0],c[2]});
        }
    	priority_queue<pair<int,int>, vector<pair<int,int>>, cmp> q;
    	int to, distance, total = 0, edge = 0;
        vis[1] = true;
        for(auto& e : edges[1])
            q.push(e);           
    	while(!q.empty())
    	{
    		to = q.top().first;
    		distance = q.top().second;
    		q.pop();
    		if(!vis[to])
            {
                vis[to] = true;
                total += distance;
                edge++;
                if(edge == N-1)
                    return total;
                for(auto& e : edges[to])
                    q.push(e);           
            }
    	}
    	return -1;
    }
};

492 ms 40.9 MB

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/08/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 1. 题目
  • 2. 解题
    • 1. Kruskal
      • 2. prim
      相关产品与服务
      对象存储
      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档