当前位置: 首页 > article >正文

冗余连接 代随写法的C#版本

卡码网108 与 力扣684题 总体来说一摸一样。与1971寻找图中是否存在路径很相似

因为初学 学习的代随的写法 就一直延续了没有用里扣的写法

108. 冗余连接

题目描述

有一个图,它是一棵树,他是拥有 n 个节点(节点编号1到n)和 n - 1 条边的连通无环无向图(其实就是一个线形图),如图:

现在在这棵树上的基础上,添加一条边(依然是n个节点,但有n条边),使这个图变成了有环图,如图:

先请你找出冗余边,删除后,使该图可以重新变成一棵树。

输入描述

第一行包含一个整数 N,表示图的节点个数和边的个数。

后续 N 行,每行包含两个整数 s 和 t,表示图中 s 和 t 之间有一条边。

输出描述

输出一条可以删除的边。如果有多个答案,请删除标准输入中最后出现的那条边。

输入示例
3
1 2
2 3
1 3
输出示例
1 3
提示信息

图中的 1 2,2 3,1 3 等三条边在删除后都能使原图变为一棵合法的树。但是 1 3 由于是标准输出里最后出现的那条边,所以输出结果为 1 3

数据范围:

1 <= N <= 1000.

思路:我们可以从前向后遍历每一条边(因为优先让前面的边连上),边的两个节点如果不在同一个集合,就加入集合(即:同一个根节点)。关键:如果边的两个节点已经出现在同一个集合里,说明着边的两个节点已经连在一起了,再加入这条边一定就出现环了。

具体解决问题的模板还是那个模板写法 先全初始化Unifind  然后路径压缩 Find  在就是合并操作Join 和最后的判断是不是在一个集合时的操作 IsSame

代码:

using System;

public class Program {
    public static void Main(string[] args) {
        int N;
        string[] firstLine = Console.ReadLine().Split();
        N = int.Parse(firstLine[0]);

        Unifind un = new Unifind(N + 1);  // 注意:N + 1 是因为索引从 1 开始
        for (int i = 0; i < N; i++) { //不断输入 初始化完整个 father 数组
            string[] edge = Console.ReadLine().Split();
            int a=int.Parse(edge[0]);
            int b=int.Parse(edge[1]);

//与之前的107寻找存在的路径不同之处
            if(!un.IsSame(a,b))// 不属于同一个集合时直接将a和b合并到同一个集合
            {
                un.Join(a,b);
            }
            else                // 如果a和b属于同一个集合,说明添加这条边会形成环

           {

                // 如果它们已经在同一个集合中,则当前的边是冗余的 直接输出
                Console.WriteLine(edge[0]+" "+edge[1]); //用字符串“” 加空格来表示
                break;
            }

        }
    }
}

public class Unifind {
    private int[] father;

    public Unifind(int N) {
        father = new int[N];
        for (int i = 0; i < N; ++i) {
            father[i] = i;  // 每个节点的父节点初始化为自己
        }
    }

    // 查找操作(带路径压缩)
    public int Find(int n) {
        if (n != father[n]) {
            father[n] = Find(father[n]);  // 路径压缩
        }
        return father[n];
    }

    // 合并操作
    public void Join(int n, int m) {
        int rootN = Find(n);
        int rootM = Find(m);
        if (rootN != rootM) {
            father[rootM] = rootN;  // 将 m 的根节点指向 n 的根节点
        }
    }

    // 判断两个节点是否属于同一个集合
    public bool IsSame(int n, int m) {
        return Find(n) == Find(m);
    }
}


http://www.kler.cn/a/389341.html

相关文章:

  • 机器学习——损失函数、代价函数、KL散度
  • Unity3D学习FPS游戏(11)敌人AI巡逻(NavMesh)
  • 想租用显卡训练自己的网络?AutoDL保姆级使用教程(PyCharm版)
  • 平替 Spring 正当时!Solon v3.0.3 发布
  • AcWing 300 任务安排1
  • ODOO学习笔记(1):ODOO的SWOT分析和技术优势是什么?
  • 腾讯混元宣布大语言模型和3D模型正式开源
  • Java灵魂拷问13个为什么,你都会哪些?
  • 多用户商城系统的功能及设计和开发
  • Linux 系统结构
  • 什么是电机绕组热保护,它们如何限制浪涌电流?
  • SpringBoot基础系列学习(四):Thymeleaf模板
  • Django中间件应该怎么使用
  • 把握鸿蒙生态崛起的机遇:开发者视角的探讨
  • Linux 共享内存
  • 戴尔R930服务器增加 Intel X710-DA2双万兆光口含模块
  • 服务器被病毒入侵如何彻底清除?
  • Intern大模型训练营(四):使用Hugging Face下载模型
  • RoseTTAFold PositionalEncoding类解读
  • (C++11)委托构造函数--C++
  • 如何在Oracle应用中使用BI PUBLISHER API将RTF转换为XSL-FO
  • XGBoost算法Python代码实现
  • Iceberg 写入和更新模式,COW,MOR(Copy-on-Write,Merge-on-Read)
  • sqli-labs(第二关)
  • ThinkBook 14+ 2024 Ubuntu 触控板失效 驱动缺失问题解决
  • 腾讯自研的 Git 客户端!!【送源码】