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

发布时间:2026/10/27 18:42:57

简单并差集在学生管理系统中的应用 在最近的学习中我对并查集学得一般懂其原理但用得不深不过在最近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/10/27 8:33:33

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

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

2026/10/26 14:25:09

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

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

2026/10/27 18:39:24

1-4 用户、角色与权限体系:role/user、grant/revoke、角色继承实战

系列专栏:PostgreSQL 从零到生产实战教程阅读前置:无基础门槛,适合PG初学者、后端开发、运维工程师核心收获:彻底搞懂PG角色与用户区别、权限分级(库级/Schema级/对象级)、GRANT/REVOKE授权撤销、角色继承机…

2026/10/27 18:39:24

2025IT 监控厂商选型指南:5 款高价值运维监控产品推荐,适配数字化转型需求

01. 引言数字转型步入深水区, 企业IT架构朝着分布式、云原生, 以及国产化混合架构加速演进, 传统监控工具“工具碎片化、告警泛滥、故障根因定位难”的痛点变得愈发突出。与此同时, 信创战略持续深化, 促使企业对“自主可控、合规达标”的监控能力提更高要求, 既要实现全栈资源…

2026/10/27 18:34:24

16QAM星座图与误码率仿真:MATLAB工程实践与避坑指南

简介:16QAM星座图与误码率仿真资料面向通信原理、数字通信课程学习者及MATLAB仿真入门者,用于理解星座映射、调制解调流程与BER评估。压缩包共8个文件,均为.m脚本,体积约3KB,内容覆盖主流程调用、星座点绘制、四进制与…

2026/10/27 14:24:03

全国计算机二级C语言真题PDF高效刷题指南

简介:这份PDF是全国计算机二级C语言考试的试题与答案解析,专为备考二级C语言的考生准备。内容涵盖C语言特点与设计理念、程序基本组成单位、main函数执行流程、函数嵌套调用规则、标识符命名规范、整型实型字符型数据类型、八进制十六进制数合法形式、运…

2026/10/27 9:34:54

requests+BeautifulSoup:爬虫抓取h1标题的入门实战指南

简介:一份以实战为导向的Python爬虫入门资源,面向具备基本编程基础、希望快速掌握网络数据抓取的初学者,可解决从零编写简单爬虫的常见困惑。实例以requests库发送HTTP请求、BeautifulSoup解析HTML文档,完整演示从网页中提取 标题…

2026/10/27 0:59:21

递推最小二乘参数辨识MATLAB编程:二阶系统与渐消记忆实现

简介:这是一篇面向控制系统、信号处理与机器学习等领域学习者的最小二乘参数辨识程序说明文档。资源共包含一个docx格式文档,压缩包大小七十八KB,内容围绕递推最小二乘算法和渐消记忆最小二乘算法展开:先构造一个极点位于单位圆内…

2026/10/27 0:02:28

WorkBuddy_新建任务与工作模式19_“模式选错”的典型代价

“模式选错”的典型代价 摘要 在软件工程中,设计模式、架构模式、并发模式乃至团队协作模式的选择,往往在项目早期就决定了后续的开发效率和维护成本。本文通过多个真实场景,剖析“模式选错”带来的典型代价——包括返工成本、技术债务累积、…

2026/10/27 0:02:28

WorkBuddy_新建任务与工作模式20_新手推荐路径

新手推荐路径 摘要 在 AI 辅助开发工具快速普及的今天,新手面对最多的困惑往往不是"工具够不够强",而是"我该从哪一步开始用"。本文提出一条经过实践验证的三阶段学习路径:先从 Ask(问答式交互)起…

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

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

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