第八课 最小生成树之Kruskal

并查集+贪心算法。

/*
对于稀疏图来说,用Kruskal写最小生成树效率更好。

输入:边的起点,终点,权值 
*/
#include <iostream>
using namespace std;

#define Max 100

struct Edge
{         
    int start,end,w;
};

Edge e[Max];

int cnt, father[Max];

void init()
{
    cnt = 0;
    
    for (int i = 1; i < Max; ++i)
    {
        father[i] = i;
    }
}

int find(int x)
{
    if (x != father[x])
    {
        father[x] = find(father[x]);
    }
    
    return father[x];
}

void union_set(int i)
{
    int x = find(e[i].start);
    int y = find(e[i].end);
    
    if (x != y)
    {
        father[x] = y;
        
        cnt++;
    }
}

bool cmp(Edge a, Edge b)
{
    return a.w < b.w;
}

void Kruskal(int n, int m)
{    
    sort(e+1, e+n+1, cmp);
    
    for (int i = 1; i <= n; ++i)
    {
        if (cnt == m-1)
            break;
        
        union_set(i);
    }
}

int main()
{
    int n, m;//n为边数,m为点数 
    
    cin >> n >> m;
    
    for (int i = 1; i <= n; ++i)
    {
        cin >> e[i].start >> e[i].end >> e[i].w;
    }
    
    init();
    
    Kruskal(n, m);
    
    if (cnt == m-1)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
    
    system("pause");
}

 题目:HDU 1863 畅通工程 http://acm.hdu.edu.cn/showproblem.php?pid=1863

posted @ 2013-05-05 17:14  Norcy  阅读(226)  评论(0编辑  收藏  举报