[最小生成樹] leetcode 1135 Connecting Cities With Minimum Cost


problem: https://leetcode.com/contest/biweekly-contest-5/problems/connecting-cities-with-minimum-cost/ 

      雙周賽題目。此題就是沒有什么變化的最小生成樹,以下給出兩種經典解法:

 

(1).並查集

        首先假設所有的頂點都是一棵單獨的樹,之后依次選擇權重最小的邊,使得它連接兩棵不同的樹,並將兩棵樹合並為一棵樹。當選擇了N - 1條邊(只剩下一棵樹)的時候,意味着得到了最小生成樹。

struct edge
{
    int vertex1;
    int vertex2;
    int value;
    edge(int v1, int v2, int val) :vertex1(v1), vertex2(v2), value(val) { }
    friend bool operator<(const edge& e1, const edge& e2)
    {
        return e1.value > e2.value;
    }
};

class Solution {
public:
    vector<int> nums;
    int Find(int x)
    {
        while(x != nums[x])
        {
            x = nums[x];
        }
        return x;
    }
    void Union(int x, int y)
    {
        int px = Find(x);
        int py = Find(y);
        if(px != py)
        {
            nums[px] = py;
        }
    }
    bool InSameSet(int x,int y)
    {
        int px = Find(x);
        int py = Find(y);
        return px == py;
    }
    int minimumCost(int N, vector<vector<int>>& conections) {
        
        priority_queue<edge> pq;
        
        nums.resize(N + 1);
        for(int i = 1; i <= N; i++)
        {
            nums[i] = i;
        }
     
        for(int i = 0; i < conections.size();i++)
        {
            int v1 = conections[i][0];
            int v2 = conections[i][1];
            int val = conections[i][2];

            pq.push(edge(v1, v2, val));
        }
        
        int res = 0;
        int edgeNum = 0;
        while(true)
        {
            if(pq.empty()) return -1;
            edge cur = pq.top();
            pq.pop();
            
            if(InSameSet(cur.vertex1, cur.vertex2))
            {
                continue;
            }
            res += cur.value;
            edgeNum++;
            if(edgeNum == N - 1) return res;
            Union(cur.vertex1, cur.vertex2);
        }
        return res;       
    }
};

 

(2) 寬度優先搜索

        從一個空集合開始,加入任一頂點,並找到該集合中頂點連接的權重最小的邊,把該邊連接的點也加入集合。直到所有的點都加入了集合,意味着找到了最小生成樹。

class Solution {
public:
    vector<unordered_map<int,int>> graph;
    int minimumCost(int N, vector<vector<int>>& conections) {
        graph.resize(N + 1);
     
        for(int i = 0; i < conections.size();i++)
        {
            int v1 = conections[i][0];
            int v2 = conections[i][1];
            int val = conections[i][2];

            if(graph[v1].find(v2) != graph[v1].end())
            {
                graph[v1][v2] = min(graph[v1][v2], val);
                graph[v2][v1] = min(graph[v2][v1], val);
            }
            else
            {
                graph[v1][v2] = val;
                graph[v2][v1] = val;               
            }
        }
        
        priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;

        for(int i = 1;i <= N;i++)
        {
            if(graph[i].size() == 0)
            {
                 return -1;
            }
        }
        vector<bool> visit(N + 1, false);

        pq.push({0,1});
        
        int res = 0;
        int count = 0;
        while(!pq.empty())
        {
            auto cur = pq.top();
            pq.pop();
            if(visit[cur.second]) continue;
           
            res += cur.first;
            visit[cur.second] = true;
            count++;
            
            
            if(count == N) break;
            for(auto& neighbor : graph[cur.second])
            {
                if(!visit[neighbor.first])
                {
                    pq.push({neighbor.second, neighbor.first});
                }
            }   
            
        }
       
        if(count != N) return -1;
        
        return res;
    }
};

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM