Luogu P1547 Out of Hay的题解

蒟蒻第一篇题解,写得可能不大尽如人意,

望大佬指点蒟蒻的题解,多谢。

原题查看

我个人认为这道题就是Kruskal算法的模板题,还是比较简单的

Kruskal(克鲁斯卡尔):一种巧妙利用并查集来求最小生成树的算法。

实现过程:

过程大致如下:

  1. 初始化,将并查集初始化,每个点的父节点为其本身。
  2. 计数器归零。
  3. 把所有边的权值从小到大快排。
  4. 具体的Kruskal算法:
 1 for(int i=1;i<=m;i++)
 2 {
 3     int f1=Find(e[i].x),f2=Find(e[i].y);
 4     if(f1!=f2)
 5     {
 6         ans=max(ans,e[i].dis);
 7         fa[f1]=f2;
 8         if(k==n-1) break;
 9         k++;
10     }
11 }

 

完整代码如下(有一丢丢注解)

code

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,k=1,fa[100005];
struct node//用结构体表示边
{
    int x,y,dis;
}e[100005];
bool cmp(node x,node y)
{
    return x.dis<y.dis;
}
int Find(int x)//查找x的祖宗
{
    if(fa[x]!=x) fa[x]=Find(fa[x]);
    return fa[x];
}
void Union(int x,int y)//将x,y并为一个集合
{
    if(Find(x)!=Find(y))
        fa[Find(x)]=Find(y);
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        fa[i]=i;
    for(int i=1;i<=m;i++)
        cin>>e[i].x>>e[i].y>>e[i].dis;
    sort(e+1,e+m+1,cmp);//快排
    for(int i=1;i<=m;i++)
    {
        int f1=Find(e[i].x),f2=Find(e[i].y);
        if(f1!=f2)//如果祖宗不同
        {
            ans=max(ans,e[i].dis);//更新答案
            fa[f1]=f2;
            if(k==n-1) break;//至少连点数-1条边
            k++;//计数器++
        }
    }
    cout<<ans<<endl;//输出
    return 0;
}

 

 

提交评测记录

posted @ 2019-07-26 11:27  iDarkForest  阅读(112)  评论(0)    收藏  举报