复习--最小生成树&&并查集

我个人比较喜欢Kruskal算法,所以就把这个方法写了一下,但过不了洛谷,70分。

思路是先全读入,再排序,一条一条加边。运用并查集。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct s{
    int h;
    int t;
    int w;
};
int fa[30000]; 
bool cmp(s a,s b)
{
    return a.w < b.w;
}
int find(int a)
{
    if(fa[a] != a)  //不是while 
    fa[a] = find(fa[a]);
    return fa[a];
}
void un(int a,int b)
{
    a = find(a);
    b = find(b);
    if(a != b)
    fa[b] = a;
}
bool judge(int a,int b)
{
    a = find(a);
    b = find(b);
    if(a != b)
    return false;
    else return true;
}
s side[10001];
int m,n,k,tot = 0,num = 1;
int main()
{
    cin>>n>>k;
    for(int i = 1;i <= n;i++)
    {
        fa[i] = i;
    }
    for(int i = 1;i <= k;i++)
    {
        cin>>side[i].h>>side[i].t>>side[i].w;
        //tot += side[i].w;
    }
    sort(side + 1,side + k + 1,cmp);
    tot = 0;
    for(int i = 1;i <= k;i++)
    {
        if(judge(side[i].h,side[i].t) == false)
        {
            un(side[i].h,side[i].t);
            tot += side[i].w;
            num++;
        }
        if(num == n)
        break;
    }
    cout<<tot<<endl;
    return 0;
}
/*
5 5
1 2 8
1 3 1
1 5 3
2 4 5
3 4 2
*/

 再加一个并查集的板子,日后备用。

#include<iostream>
using namespace std;
int fa[100],m,n,x,y,z;
int find(int a)
{
    if(fa[a] != a)
    fa[a] = find(fa[a]);
    return fa[a];
}
bool judge(int a,int b)
{
    a = find(a);
    b = find(b);
    if(a != b)
    return false;
    else
    return true;
}
void un(int a,int b)
{
    a = find(a);
    b = find(b);
    if(a != b)
    fa[b] = a;
}
int main()
{
    cin>>m>>n;
    for(int i = 0;i < m;i++)
    fa[i] = i;
    for(int i = 0;i <n;i++)
    {
        cin>>x>>y>>z;
        if(x == 1)
        {
            if(judge(y,z) == false)
            un(y,z);
        }
        else
        {
            if(judge(y,z) == true)
            cout<<"Yeah"<<endl;
            else
            cout<<"No,opps"<<endl;
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/DukeLv/p/8401208.html