SDU_week6_D_CSP201812-4 - 数据中心(Kruskal最小生成树变体)

题目描述

在这里插入图片描述
在这里插入图片描述

题目分析

csp通病,balabala说一堆,实际上就是给定无向图,求解一颗生成树,使得最大边权最小
即求一棵最小瓶颈生成树,由性质知最小生成树一定是最小瓶颈生成树
问题转化为求一棵最小生成树,并记录其中最大边权。题目中“数据中心”属于无用信息。
上一题已经用了Prim,本题使用Kruskal板子跑一遍即可。

一些感悟

对比了自己的Kruskal和学长的Kruskal,深深自愧不如。下面来分析分析一些好的point:

  1. 重载<可以放在结构体中一行解决,避免写cmp函数(不过考虑到个人习惯我还是喜欢使用cmp比较函数),常用const修饰变量和函数以防止莫名奇妙的修改。
struct edge
{
    int u, v, w;
    bool operator <(const edge& t)const { return w < t.w; }//不使用cmp比较函数的重载方法
}e[100009];
  1. 巧用函数的返回值。操作类函数中,我常常喜欢使用void类型,但有时可能需要额外数组记录信息。例如在unite()函数中,返回值为bool类型可以直接判断是否要进行后续操作。
bool unite(int x, int y)
{
    x = find(x); y = find(y);
    if (x == y)return false;//已经在一组
    parent[x] = y; return true;//不在一组,合并
}

代码

#include <iostream>
#include<algorithm>
using namespace std;

struct edge
{
    int u, v, w;
    bool operator <(const edge& t)const { return w < t.w; }//不使用cmp比较函数的重载方法
}e[100009];

int parent[50009];
void init(int n)
{
    for (int i = 1; i <= n; i++)parent[i] = i;
}
int find(int x)
{
    return parent[x] == x ? x : parent[x] = find(parent[x]);
}
bool unite(int x, int y)
{
    x = find(x); y = find(y);
    if (x == y)return false;//已经在一组
    parent[x] = y; return true;//不在一组,合并
}

int n, m, start;//n个节点m条边,数据中心为start(貌似start没什么用)
int kruskalReturnMax()
{
    sort(e + 1, e + m + 1);
    int cnt = 0, ans = 0;
    for (int i = 1; i <=m; i++)
    {
        if (unite(e[i].u, e[i].v))
        {
            ans = max(ans, e[i].w);
            if (++cnt == n - 1)break;//生成树m=n-1,及时终止提高速度
        }
    }
    return cnt == n-1 ? ans : -1;//成功生成返回ans,否则返回-1
}


int main()
{
    cin >> n >> m >> start;
    init(n);
    for (int i = 1; i <=m; i++)
        cin >> e[i].u >> e[i].v >> e[i].w;
    cout << kruskalReturnMax();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值