天梯赛 L2 家庭房产

本文介绍了如何使用并查集解决一道名为'天梯赛L2家庭房产'的题目。通过链接可以查看具体题目详情。文章详细阐述了利用并查集的数据结构和算法思路来解决家庭房产的关联问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:点击打开链接

思路:并查集

#include <bits/stdc++.h>
using namespace std;
int fa[10000],house[10000],area[10000],book[10000];
struct node{
    int minNum,cnt;
    double averHour,averArea;
    node(int a,int b,double c,double d):minNum(a),cnt(b),averHour(c),averArea(d){}
    bool operator<(const node &b)const{
        if(fabs(averArea - b.averArea) > 1e-7){
            return averArea > b.averArea;
        }
        else{
            return minNum < b.minNum;
        }
    }
};
int father(int x){
    return fa[x] = (x == fa[x]?x:father(fa[x]));
}
void merge(int a,int b){
    int x = father(a);
    int y = father(b);
    if(x != y){
        fa[x] = y;
    }
    return;
}
set<int> s;
map<int,int> m1,m2,m3,m4;
vector<node> v;
int main(){
    int n;
    int id,f,m,k,son;
    for(int i = 0;i < 10000;i++){
        fa[i] = i;
        house[i] = 0;
        area[i] = 0;
        book[i] = 0;
    }
    scanf("%d",&n);
    for(int i = 0;i < n;i++){
        scanf("%d%d%d",&id,&f,&m);
        book[id] = 1;
        if(f != -1){
            merge(id,f);
            book[f] = 1;
        }
        if(m != -1){
            merge(id,m);
            book[m] = 1;
        }
        scanf("%d",&k);
        for(int j = 0;j < k;j++){
            scanf("%d",&son);
            merge(id,son);
            book[son] = 1;
        }
        scanf("%d%d",&house[id],&area[id]);
    }
    for(int i = 0;i < 10000;i++){
        if(book[i] == 0) continue;
        int x = father(i);
        s.insert(x);
        if(m1.find(x) == m1.end() || m1[x] > i){
            m1[x] = i;
        }
        m2[x]++;
        m3[x] += house[i];
        m4[x] += area[i];
    }
    for(set<int>::iterator it = s.begin();it != s.end();it++){
        v.push_back(node(m1[*it],m2[*it],(double)m3[*it] / m2[*it],(double)m4[*it] / m2[*it]));
    }
    sort(v.begin(),v.end());
    printf("%d\n",v.size());
    for(int i = 0;i < v.size();i++){
        printf("%04d %d %.3f %.3f\n",v[i].minNum,v[i].cnt,v[i].averHour,v[i].averArea);
    }
    return 0;
}







### 天梯赛 L2 题目解析 天梯赛 L2 层次的练习题涵盖了多种数据结构和算法的应用,难度相对较高。以下是部分具有代表性的题目及其特点: #### 数据结构类题目 - **链表操作** - `L2-002` 链表去重是一个典型的涉及单向链表的操作问题,在处理过程中需要注意边界条件以及如何高效地标记已经访问过的节点[^1]。 - **二叉树构建与查询** - 对于`L2-004` 和 `L2-011`这类关于二叉搜索树或者一般二叉树的问题,则更侧重考察选手对于不同遍历方式的理解程度,比如通过给定的前序/后序加中序序列来重建一棵唯一的二叉树。 - **堆结构理解** - 如`L2-012` 关于堆性质验证的任务则要求掌握最大(小)根堆的概念,并能够据此设计合理的检验逻辑。 #### 图论基础 - **连通性分析** - 类似于`L2-007`家庭房产这样的并查集应用场景可以用来解决集合之间的合并查找问题;而像`L2-013`红色警报则是基于图上进行连通区域探测的例子之一。 - **最短路径计算** - 虽然具体提到的是Dijkstra算法[^2],但在实际比赛中也可能遇到其他类型的最优化路径求解场景。 #### 字符串匹配技巧 - **模式识别** - 当涉及到字符串时(如`L2-008`最长对称子串),Manacher算法提供了一种高效的中心扩展方法用于寻找回文串的最大长度。 #### 组合数学思维训练 - **排列组合枚举** - 座位安排(`L2-010`)不仅考验编程能力还隐含着一定的离散数学背景知识,特别是当存在多组约束条件下最优方案的选择策略。 为了更好地准备这些挑战,建议深入学习上述各个知识点对应的经典理论书籍或在线教程资源,同时积极参与刷题实践以积累实战经验。此外,关注历年真题解析有助于熟悉命题风格和发展趋势。 ```cpp // 示例代码片段展示了一个简单的 Dijkstra 实现 #include <queue> using namespace std; struct Node { int id, dist; bool operator<(const Node& rhs)const{ return this->dist > rhs.dist; // 小顶堆 } }; priority_queue<Node> pq; vector<int> dijkstra(int start){ vector<int> dis(n+1, INF); dis[start]=0; pq.push({start, 0}); while(!pq.empty()){ auto t=pq.top(); pq.pop(); if(st[t.id]) continue; st[t.id]=true; for(auto i:g[t.id]){ int j=i.first; int weight=i.second; if(dis[j]>dis[t.id]+weight){ dis[j]=dis[t.id]+weight; pq.push({j, dis[j]}); } } } return dis; } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值