摘要: 最小生成树的一些衍生问题,比较难。
【对算法,数学,计算机感兴趣的同学,欢迎关注我哈,阅读更多原创文章】
我的网站:潮汐朝夕的生活实验室
我的公众号:算法题刷刷
我的知乎:潮汐朝夕
我的github:FennelDumplings
我的leetcode:FennelDumplings
题目: P4208 最小生成树计数
算法: Kruskal
题解参考: 力扣1489-找到最小生成树里的关键边和伪关键边;4208题解
题目: 356. 次小生成树
算法: 树上倍增
题解参考: LCA,树上倍增,树上差分>
题目: 348. 沙漠之王
算法:01分数规划,值域二分
题解参考: 01分数规划
题目: k小生成树(kmst)
题解参考: k小生成树题解
题目:1584. 连接所有点的最小费用
算法:邻接矩阵 + Prim,O(N2)
题解参考:
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
| class Solution { public: int minCostConnectPoints(vector<vector<int>>& points) { int n = points.size(); vector<vector<int>> adj(n, vector<int>(n, 0)); for(int i = 0; i < n - 1; ++i) for(int j = i + 1; j < n; ++j) { int d = manhattan(points[i][0], points[i][1], points[j][0], points[j][1]); adj[i][j] = adj[j][i] = d; } int cost = 0; vector<int> visited(n, false); vector<int> d(n, INT_MAX / 2); d[0] = 0; for(int cnt = 1; cnt <= n; ++cnt) { int minx = INT_MAX / 2; int minx_j = -1; for(int j = 0; j < n; ++j) { if(!visited[j] && d[j] < minx) { minx = d[j]; minx_j = j; } } cost += minx; visited[minx_j] = true; const int &i = minx_j; for(int j = 0; j < n; ++j) if(!visited[j] && d[j] > adj[i][j]) d[j] = adj[i][j]; } return cost; }
private: int manhattan(int x1, int y1, int x2, int y2) { return abs(x1 - x2) + abs(y1 - y2); } };
|
算法2: 莫队算法 + 树状数组
题解参考: