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

Cables and Servers

F - Cables and Servers

问题陈述

有 NN 台服务器,编号从 11 到 NN,以及 MM 根电缆,编号从 11 到 MM。
电缆 ii 双向连接服务器 AiAi​ 和 BiBi​。

通过执行以下操作若干次(可能为零次),使所有服务器通过电缆连接。

  • 操作:选择一根电缆,并将其一端重新连接到另一台服务器。

找出所需的最小操作次数,并输出实现此最小值的操作序列。

约束条件

  • 2≤N≤2×1052≤N≤2×105
  • N−1≤M≤2×105N−1≤M≤2×105
  • 1≤Ai,Bi≤N1≤Ai​,Bi​≤N
  • 所有输入值均为整数。

输入

输入通过标准输入以以下格式给出:

NN MM
A1A1​ B1B1​
A2A2​ B2B2​
⋮⋮
AMAM​ BMBM​

输出

设最小操作次数为 KK。打印 K+1K+1 行。

  • 第一行应包含 KK。
  • 第 (i+1)(i+1) 行应包含三个用空格分隔的整数:在第 ii 次操作中选择的电缆编号、原本连接在该端的服务器编号,以及操作后连接的服务器编号,按此顺序。

如果有多个有效解答,接受其中任何一个。

示例 1

InputcopyOutputcopy
4 5
1 1
1 2
2 1
3 4
4 4
1
1 1 3

通过将连接到服务器 11 的电缆 11 的一端重新连接到服务器 33,可以使服务器通过电缆连接。

例如,将连接到服务器 44 的电缆 55 的一端重新连接到服务器 11,或者将连接到服务器 22 的电缆 22 的一端重新连接到服务器 33,也会使所有服务器连接,并被视为正确。

示例 2

InputcopyOutputcopy
4 3
3 4
4 1
1 2
0

可能不需要任何操作。

示例 3

InputcopyOutputcopy
5 4
3 3
3 3
3 3
3 3
4
1 3 5
2 3 4
3 3 2
4 3 

思路:

Q1:这题是要让所有电脑连通在一起的最小操作序列,我们能否将问题拆分开来

A1:可以将问题分解为 如何将一整个图变成连通图 和 怎样才能有最小的操作序列

Q2:如何将一整个图变成连通图

A2:题目中已经说了,改变一条边的端点,从而使整张图连通,我们想到了并查集

Q3:我们要去改变哪些边的端点呢?

A3:如果说,某两个点,在去掉这条边后,仍然在一张连通图中(即成环的边),就说明这条边可以用,改变后不影响结果

Q4:我们这样是否是有最小的操作序列呢

A4:我们每次只对两个没有连通的分量,链接只一次,一定是最小的操作序列

 代码:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int n, k, a[200010],b[200010], c[200010],d[200010];
//a用于并查集数组,b第 i 次操作中选择的电缆编号
//c以及操作后连接的服务器编号,d原本连接在该端的服务器编号
int x, y;
int cha(int i) {
	if (a[i] != i) {
		return a[i] = cha(a[i]);
	}
	else {
		return a[i];
	}
}
int main() {
	scanf("%d %d", &n, &k);
	for (int i = 1;i <= n;i++) {
		a[i] = i;
	}//给a赋值
	int j = 0;
	for (int i = 1;i <= k;i++) {
		scanf("%d %d", &x, &y);
		if (cha(x) == cha(y)) {
			d[j] = y;
			b[j++] = i;
		}//将“无用”的线记录下来
		a[cha(x)] = cha(y);//并集
	}
	int sum = 0;
	for (int i = 1;i <=n;i++) {
		if (a[cha(i)] == i) {
			c[sum++] = i;
		}
	}//搜索有几个没有相接的服务器
	sum -= 1;
	printf("%d\n", sum);
	for (int i = 0;i < sum;i++) {
		if (cha(d[i]) == cha(c[i])) {
			int dd = c[i];
			c[i] = c[sum];
			c[sum] = dd;
		}//每条边都有头点,n-1条边将n-1个点于头点相连,最终只有一个点(在头点中)没链接;
         //因此可以放在最后
		printf("%d %d %d\n", b[i],d[i],c[i]);
		a[c[i]] = cha(d[i]);//将连接的并集,防止重复链接
	}
	return 0;
}


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

相关文章:

  • 中电联协议对接互联互通实现充电桩小程序成熟搭建
  • 计算机毕业设计SpringBoot+Vue.js医院住院管理系统(源码+lw文档+PPT+讲解视频)
  • w212球队训练信息管理系统设计与实现
  • Vue的简单入门 一
  • Java 大视界 -- 量子计算时代 Java 大数据的潜在变革与应对策略(88)
  • Java知识速记:ArrayList与LinkedList的区别
  • java nio 原理 非阻塞IO Netty
  • 数据结构 day 07
  • Java八股文详细文档.2(基于黑马、ChatGPT、DeepSeek)
  • Linux软件编程——标准IO(2025.2.14)
  • 微信小程序 - 组件
  • DELL 服务器 OpenManage监控指标释义
  • 2024年认证杯SPSSPRO杯数学建模A题(第二阶段)保暖纤维的保暖能力全过程文档及程序
  • [生信云问题分析] 为什么医院/单位/校园网络,无法通过ssh协议访问服务器
  • Macos下载 unity 的步骤与使用方法
  • 架构——LVS负载均衡主要模式及其原理、服务水平、优缺点
  • 正则表达式(竞赛篇)
  • Spring Boot 从 2.7.x 升级到 3.3注意事项
  • VS编译生成moc文件
  • 【Docker】容器被停止/删除的方式及命令:全面解析与实践指南