简单并差集在学生管理系统中的应用

发布时间:2026/9/8 19:49:39

简单并差集在学生管理系统中的应用 在最近的学习中我对并查集学得一般懂其原理但用得不深不过在最近Java的期末项目里我的主题是高考模式下的学生成绩管理系统我的思考就停留在了新高考的312的选科目上那是不是同组合的人要放在一块呢结合我最近学过的知识并差集刚好可以写它也许这有点小题大做但我就得自己学的好不好还是实践才知道具体说明如下引用洛谷P1551# P1551 亲戚## 题目描述若某个家族人员过于庞大要判断两个是否是亲戚确实还很不容易现在给出某个亲戚关系图求任意给出的两个人是否具有亲戚关系。规定x 和 y 是亲戚y 和 z 是亲戚那么 x 和 z 也是亲戚。如果 xy 是亲戚那么 x 的亲戚都是 y 的亲戚y的亲戚也都是 x 的亲戚。## 输入格式第一行三个整数 n,m,p,(n,m,p 5000分别表示有 n 个人m个亲戚关系询问 p 对亲戚关系。以下 m行每行两个数 M_iM_j1 M_i,M_j n表示 M_i 和 M_j具有亲戚关系。接下来 p行每行两个数 P_i,P_j询问 P_i 和 P_j 是否具有亲戚关系。## 输出格式p 行每行一个 Yes 或 No。表示第 i个询问的答案为“具有”或“不具有”亲戚关系。输入输出样例输入 #16 5 31 21 53 45 21 31 42 35 6输出 #1YesYesNo很显然这是一个模板题要实现简单的并查集代码如下#include bits/stdc.h using namespace std; const int N100010; int parent[N];//表示它的父节点 int Mysize[N];//表示他的长度即根结点以下挂的长度 int Mystack[N];//提供一个空间去临时存他的状态 void init(int n) { for (int i1;in;i) { parent[i]i;//初始化每个都是自己的父亲 Mysize[i]1;//初始化每个集合的长度都是1 } } //这是非递归写法也可以写成 /* int find(int n){//递归写法也具备压缩性 if(parent[n]!n){ parent[n]find(parent[n]); } return parent[n]; } */ int find(int n) {//find方法是去找他的根节点在这里实现了压缩功能 int size0; while (n!parent[n]) { Mystack[size]n;//压入栈中,收入不是根节点的节点 nparent[n];//找父节点,就是让n向上指直到找到跟节点 } while ( size0) { parent[Mystack[--size]]n;//弹出栈将所有节点都指向根节点 } return n;//返回根节点 } void Union(int x,int y) {//合并两个集合 //首先去找他的根节点 int fxfind(x); int fyfind(y); if (fx!fy) {//在不同的情况下合并,我们这里是大吞小 if (Mysize[fx]Mysize[fy]) {//大的合并到小的 Mysize[fx]Mysize[fy]; parent[fy]fx;//让原来小容量的结点指向大的根节点 }else { Mysize[fy]Mysize[fx];; parent[fx]fy; } } } bool is_same_set(int x,int y) { return find(x)find(y);//判断是否同一个集合 } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int n,m,p;//n个人m个关系p个查询 cinnmp; init(n);//初始化并查集 for(int i0;im;i){ int a,b; cinab; Union(a,b);//合并所有集合 } while(p--0){ int a,b; cinab; if(is_same_set(a,b)){//判断是否同一个集合就说明具有亲戚关系 coutYesendl; }else{ coutNoendl; } } return 0; }而我们在学生成绩管理系统里首先定义UnionFind类代码如下import java.util.*; public class UnionFind { private HashMapStudent, Student parent;//用于记录父节点 private HashMapStudent, Integer rank;//用于记录树的深度,有利于他的合并相当与模板里的Mysize[]; public UnionFind() { parent new HashMap(); rank new HashMap(); } public void addNode(Student s){//添加节点 if(!parent.containsKey(s)){//如果之前节点不存在则添加 parent.put(s, s);//父节点设为自己相当于模板里的parent[x] x; rank.put(s, 1);//树的深度设为1相当于模板里的Mysize[x] 1; } } public Student find(Student s){//查询节点,这里是递归写法 if(parent.get(s) ! s){ parent.put(s, find(parent.get(s))); } return parent.get(s); } public void union(Student s1, Student s2){//合并节点 Student p1 find(s1); Student p2 find(s2); if(p1 ! p2){ if(rank.get(p1) rank.get(p2)){ rank.put(p1, rank.get(p1) rank.get(p2)); parent.put(p2, p1); } else { rank.put(p2, rank.get(p1) rank.get(p2)); parent.put(p1, p2); } } } public boolean isSameSet(Student s1, Student s2){//判断两个节点是否属于同一个集合 return find(s1) find(s2); } }和前面的模板思路相同就是加入学生类和哈希表在测试类里面我们就使用它private static UnionFind uf new UnionFind();//先创建对象作为全局变量方法里的应用public static void addStudent(Student s) throws Exception { synchronized (lock) {//因为我同时用了多线程 String id s.getId(); if (map.containsKey(id)) throw new Exception(学号已存在); map.put(id, s); uf.addNode(s); String comb getCombination(s);//此方法是用于返会所选的几门科目312 /*public static String getCombination(Student s) { return s.getFirstSubject() , s.getSecondSubject1() , s.getSecondSubject2(); }*/ for (Student s1 : map.values()) {//相同组合里的合并到同一个集合里 if (!s1.getId().equals(id) getCombination(s1).equals(comb)) { uf.union(s, s1); break; } } } } //判断学生是否在同已选科目里 public static boolean isSameGroup(String id1, String id2){ Student s1 map.get(id1); Student s2 map.get(id2); if(s1 null || s2 null){ return false; } return uf.isSameSet(s1, s2); } //统计同组合的人数 public static void statGroupSimple() { MapStudent, Integer groupCount new HashMap();//用哈希表类记录个数 for (Student s : map.values()) { Student root uf.find(s); groupCount.put(root, groupcount.getOrDefault(root, 0) 1);//这是简写和以下是一样的 /* if(groupCount.containsKey(root)){ int countgroupCount.get(root); groupCount.put(root,count1); }else{ groupCount.put(root,1); }*/ } System.out.println(选科组合总种类 groupCount.size()); int i 1; for (Student root : groupCount.keySet()) { String combo getCombination(root); int people groupCount.get(root); out.println(第 i 种 组合 combo 人数 people);//一般都用PrintWriter来输出 i; } } //查询同选科的学生用其中一人的学号 public static void showSameGroup(String id) { // 根据学号找学生 Student target map.get(id); if (target null) { out.println(该学号不存在); return; } // 找这个学生根节点 Student root uf.find(target); out.println( 同选科所有同学 ); // 遍历所有学生根节点一样就是同选科 for (Student s : map.values()) { if (uf.find(s) root) { out.println(学号 s.getId() 姓名 s.getName()); } } } //同样的删除也是一个道理 public static void DeleteSameGroup(String id) { // 根据学号找目标学生 Student target map.get(id); if (target null) {//注意要判断一下 System.out.println(学号不存在无法删除); return; } // 找到这个选科组的根节点 Student root uf.find(target); // 先收集要删除的所有学号 ArrayListString deleteList new ArrayList(); for (Student s : map.values()) { if (uf.find(s) root) {//用find方法去找同一集合的学生 deleteList.add(s.getId()); } for (String id : deleteList) { map.remove(id);//通过学号来删除 } }简单总结一下我在写这个管理系统的时候并查集确实是一时想到的使用过程中也改过多次总的来说应用得很浅很浅比起大难的一些算法题来说应用的很浅了力扣情侣牵手逻辑思维上比这个更深以及好多不会写的题目不过这也是我的一个创新吧我也在慢慢实现它其实我对并查集的使用可能解释这个水平了还有好多应用我还没想到的希望大佬们多给建议我的提升空间很大算法的熟练是刷题和应用出来的就好像我听来做左神的课都懂了不写题那就白学了没啥更多好说的加油
延伸阅读

更多相关文章

2026/9/8 19:49:39

采用单级PFC+LLC集成架构,因为变压器的一次原边是一端接地的,类似变压器充放电原理。半桥开关电源和LLC开关电源在开关管回路电压上的核心区别。注意文中传统半桥和半桥LLC区别

在单级PFCLLC集成架构中,变压器原边一端接地的设计确实与传统半桥结构不同,其电压对称性由谐振网络和开关时序动态生成,而非依赖分压电容‌。这种设计通过类似“充放电交替反转”的机制,实现能量的高效传递。一、一次侧一端接地的…

2026/9/8 19:44:39

Clawdbot深度解析:智能体编码、云端沙箱与无人值守自动化

1. Clawdbot是什么,以及它为什么值得单独拿出来聊Clawdbot这个项目名,最近在AI编程圈子里出现的频率明显高了起来。虽然和Claude系工具存在一定血缘关系,但Clawdbot并不是又一个简单包装的编码助手,而是一套以"agentic codin…

2026/9/8 20:49:54

Hermes:基于大模型的自动化代码评审工具实践指南

先把结论放前面:我自己在 GitHub 仓库上跑过一段时间的 Hermes,它不只是一个 PR 辅助小玩具,而是能把“开 PR → 读 diff → 给评论 → 挂状态”这整条链路交给自动化代码评审去执行的一整套方案。如果你还在靠人工逐条翻 Pull Request&#…

2026/9/8 20:49:54

MAX31855热电偶信号调理芯片原理与工业应用指南

简介:本资源是一套基于STM32F4平台的MAX31855热电偶温度检测完整嵌入式工程,面向嵌入式开发初学者与工业测温应用开发者,解决热电偶高精度测温中冷端补偿、SPI通信驱动、异常诊断及低功耗管理等核心实现难题。包内共193个文件,涵盖…

2026/9/8 20:49:53

Claude Code完全配置实战:从安装、MCP到Skills全攻略

1. 整体认知框架:Claude Code 到底解构到哪一步了先说结论:这篇文章是这个系列的收尾篇,也是我认为最重要的一篇。前面十几篇我们分别聊了 Claude Code 的安装流程、CLI 参数调优、MCP 服务器接入、VSCode 插件联动、本地模型切换、Token 消耗…

2026/9/8 20:49:53

STM32F4工业级I2C驱动PCAP04电容传感器实战指南

简介:本资源是一份面向嵌入式开发工程师与物联网硬件工程师的I2C通信实战参考方案,聚焦Cuptime2主控平台与PCAP04触摸控制器之间的可靠交互实现。资源系统梳理了I2C协议配置要点(时钟频率、引脚复用、从机地址设定)、通信流程&…

2026/9/8 20:49:53

阿里开源skill-up:Agent Skill评测工具实战指南

写评测脚本、造评测数据,到头来发现最大的瓶颈根本不是模型能力,而是没法量化评估“这组配置到底比之前好在哪里”。尤其是Agent应用里大量使用Skill(技能)的时候,问题更明显:同一个问题,今天跑…

2026/9/8 20:44:52

零基础跑通金融风控系统:贷款违约预测实战指南

简介:本资源是阿里云出品的「零基础入门金融风控—贷款违约预测」实战课程包,面向Python初学者及金融科技入门学习者,聚焦信贷风控核心场景,系统讲解如何利用机器学习建模识别高风险贷款申请者。压缩包共58.83MB,含完整…

2026/9/8 7:15:10

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/8 7:15:15

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/8 7:15:10

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/8 0:01:49

踩多轮坑才跑通|OpenClaw 3.1.0 双平台本地 AI 自动化搭建实操实录

🔹 工具简述 OpenClaw 是一款备受开发者与办公人群青睐的开源本地智能工具,凭借离线本地运行、可视化图形面板、全流程自主任务处理三大核心特点,积累了众多忠实用户。与普通对话类 AI 产品不同,它能够直接调用电脑的软硬件操作权…

2026/9/8 0:01:50

拒绝复杂命令行,Hermes Agent 一键包快速解锁智能办公能力

🔍前言 不少想要体验 Hermes Agent 办公能力的使用者,往往会被复杂的环境配置拦住使用脚步。手动下载匹配依赖、反复调整系统目录、处理命令行持续报错、修复权限异常、补全丢失核心文件等一系列操作,对普通使用者而言门槛较高,很…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/7 22:45:59

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码