POJ 1251(最小生成树)

利用并查集结构实现的Kruskal算法
是模板题

#include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <cmath>
#include <algorithm>
#define inf 0x3f3f3f3f
#define sd(a) scanf("%d",&a)
#define mem0(a) memset(a,0,sizeof(a))
typedef long long ll;
const int mod = 1e9+7;
const int maxn = 5010;

using namespace std;

int par[maxn];
int sum,Count;
struct Edge
{
    
    
    int x,y;
    int value;
} edges[maxn];
void init(int n)
{
    
    
    for(int i = 0;i <= n;i++)
        par[i] = i;
}

bool cmp(Edge a,Edge b)
{
    
    
    return a.value<b.value;
}
int Find(int x)
{
    
    
    if (x!=par[x])
        return par[x]=Find(par[x]);
    return x;
}
void Merge(int a,int b)
{
    
    
    int x=Find(a);
    int y=Find(b);
    if (x!=y)
    {
    
    
        par[x]=y;
        Count++;//记录建路条数
    }
}
int main()
{
    
    
    int n,m,Val;
    int cur;
    char temp1,temp2;
    while (sd(n)&&n != 0)
    {
    
    
        init(n);
        cur = 0;
        for (int i = 1; i < n; i++)
        {
    
    
            cin>>temp1>>m;
            while(m--)
            {
    
    
                cin>>temp2>>Val;
                edges[cur].x = i;
                edges[cur].y = temp2-'A'+1;
                edges[cur].value = Val;
                cur++;
            }
        }
        sort (edges,edges+cur,cmp);
        sum = Count = 0;
        for (int i = 0; i < cur; i++)
        {
    
    
            int a = Find(edges[i].x);
            int b = Find(edges[i].y);
            if(a != b){
    
    
                Merge(a,b);
                sum += edges[i].value;
            }
        }
        //加边的条数少于n-1条说明不能建成最小生成树
        if (Count == n-1)
            cout<<sum<<endl;
        //else
            //printf("%d\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42937838/article/details/104415070