hihoCoder-1098-kruskal

如果起始点和终止点的父节点相同,就说明它们就已经在同一个连通分量里面,说明,起始点和终止点在此之前就已经被连入同一个分量之中,如果此时还将起始点和终止点连入此分量,就会形成回路,想象一个三角形,你大概就会明白。
这一题就是kruscal的应用,但是我们的find函数还是每次最好把路径压缩一下,不然的话,就会导致查找效率的下降,然后超时。

#include <cstdio>
#include <algorithm>
using namespace std;
int pre[100010];
int n, m, res;

struct Edge {
    int from, to, cost;
    bool operator < (const Edge &a) {
        return cost < a.cost;
    }
}edge[1000010];

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

void unions(int a,int b)
{
    int x = find(a);
    int y = find(b);
    if (x!=y)
        pre[x] = y;
}

void kruskal()
{
    res = 0;
    sort(edge+1, edge+m+1);
    for (int i = 1; i <= m; i++) {
        if (find(edge[i].from)==find(edge[i].to))
            continue;
        res += edge[i].cost;
        unions(edge[i].from, edge[i].to);
    }
}

int main()
{
    while (scanf("%d%d",&n,&m)!=EOF) {
        for (int i = 1; i <= n;i++) {
            pre[i] = i;
        }
        for (int i = 1; i <= m;i++) {
            scanf("%d%d%d", &edge[i].from, &edge[i].to, &edge[i].cost);
        }
        kruskal();
        printf("%d
", res);
    }
	return 0;   
}
原文地址:https://www.cnblogs.com/xyqxyq/p/10366580.html