力扣1168水资源优化

题目

这个题目首先有节点,有双向边,而且要求最少总成本,那么我们最先想到的应该是最小生成树。

算法逻辑 

在最小生成树中有一个prim算法,个人觉得是和dijkstra非常相似甚至一模一样的,基于贪心思想的一种算法。

prim的算法过程:首先找到一个一定存在的节点,然后从这个结点开始扩展MST,每一次扩展都是找到最小的节点,然后如果这个能去到的节点之前已经访问过了,那就直接进入下一轮迭代,否则就遍历这个节点能去到的所有节点,如果没有访问过就把节点压入优先队列,一遍下一轮的访问及扩展最小生成树。一直到所有节点都访问完成,这个时候循环结束,最小生成树也就拓展好了。

题目代码

typedef pair<int, int> PII;
class Solution {
public:
    int minCostToSupplyWater(int n, vector<int>& wells, vector<vector<int>>& pipes) {
        priority_queue<PII, vector<PII>, greater<PII>> heap;
        vector<vector<PII>> graph(n + 1);
        for (int i = 0; i < wells.size(); ++i) {
            graph[0].push_back({wells[i], i + 1});
            heap.push({wells[i], i + 1});
        }
        //创建虚拟节点,连接每一条边
        for (auto& x : pipes) {
            int house1 = x[0], house2 = x[1];
            int cost = x[2];
            graph[house1].push_back({cost, house2});
            graph[house2].push_back({cost, house1});
        }
        //链接每一条给出的边
        unordered_set<int> setPrim;
        setPrim.insert(0);
        //以虚拟节点为头节点创建最小生成树
        int ans = 0;
        //只要没放满n个就继续
        while (setPrim.size() < n + 1) {
            auto tmp = heap.top(); heap.pop();
            int cost = tmp.first;
            int idx = tmp.second;
            if (setPrim.count(idx)) continue;
            setPrim.insert(idx);
            ans += cost;
            for (auto& x : graph[idx]) {
                //没在集合里面里面就把这个能去的节点压入堆中
                if (!setPrim.count(x.second)) {
                    heap.push(x);
                }
            }
        }
        return ans;
    }
};

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值