Codeforces Round 346 (Div. 2) E. New Reform 题解 并查集

news/2024/10/5 22:45:25/

New Reform

题目描述

Berland has n n n cities connected by m m m bidirectional roads. No road connects a city to itself, and each pair of cities is connected by no more than one road. It is not guaranteed that you can get from any city to any other one, using only the existing roads.

The President of Berland decided to make changes to the road system and instructed the Ministry of Transport to make this reform. Now, each road should be unidirectional (only lead from one city to another).

In order not to cause great resentment among residents, the reform needs to be conducted so that there can be as few separate cities as possible. A city is considered separate, if no road leads into it, while it is allowed to have roads leading from this city.

Help the Ministry of Transport to find the minimum possible number of separate cities after the reform.

输入格式

The first line of the input contains two positive integers, n n n and m m m — the number of the cities and the number of roads in Berland ( 2 < = n < = 100000 2<=n<=100000 2<=n<=100000 , 1 < = m < = 100000 1<=m<=100000 1<=m<=100000 ).

Next m m m lines contain the descriptions of the roads: the i i i -th road is determined by two distinct integers x i , y i x_{i},y_{i} xi,yi ( 1 < = x i , y i < = n 1<=x_{i},y_{i}<=n 1<=xi,yi<=n , x i ≠ y i x_{i}≠y_{i} xi=yi ), where x i x_{i} xi and y i y_{i} yi are the numbers of the cities connected by the i i i -th road.

It is guaranteed that there is no more than one road between each pair of cities, but it is not guaranteed that from any city you can get to any other one, using only roads.

输出格式

Print a single integer — the minimum number of separated cities after the reform.

提示

In the first sample the following road orientation is allowed: , , .

The second sample: , , , , .

The third sample: , , , , .

题面翻译

题目描述

n n n 个城市, m m m 条双向道路,没有一个城市存在自己到自己的道路,两个不同的城市间,最多有一条道路,也不能保证能从一个城市到达任意一个其他城市。

现在需要对每一条道路定向,使之成为单向道路,当然需要尽可能少地产生孤立的城市。当其他所有城市都不能到达某个城市,则称这个城市为孤立城市。要求出最少的孤立城市的个数。

输入格式

第一行,两个整数, n n n m m m

接下来 m m m 行,每行两个整数 x i x_i xi y i y_i yi,表示一条道路连接城市 x i x_i xi 和城市 y i y_i yi 的双向道路。

输出格式

一行,一个整数,表示最少的孤立城市的个数。

数据规模与约定

2 ≤ n ≤ 100000 2\le n\le 100000 2n100000 1 ≤ m ≤ 100000 1\le m\le 100000 1m100000

对于每一个合法的 x i x_i xi y i y_i yi,都有 1 ≤ x i , y i ≤ n 1\le x_i,y_i\le n 1xi,yin,且 x i ≠ y i x_i ≠ y_i xi=yi

样例 #1

样例输入 #1

4 3
2 1
1 3
4 3

样例输出 #1

1

样例 #2

样例输入 #2

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

样例输出 #2

0

样例 #3

样例输入 #3

6 5
1 2
2 3
4 5
4 6
5 6

样例输出 #3

1

原题

Codeforces——传送门
洛谷——传送门

思路

根据题意,孤立城市即是入度为 0 0 0 的点。

可以证明,对于任意一个由无向边相连的连通图,若存在环,则一定存在一种方案,使得所有无向边变为有向边后,图中不存在任意一点的入度为 0 0 0;否则一定不存在方案。

存在环时,我们可以构建这样一种方案:让构成环的所有无向边变为有向边时方向一致(即同为顺时针或者同为逆时针),这样,无向边变为有向边后环依然存在,同时,连通图内所有点被分为了两类——环中点其余点,然后再让与环中点相连的未转变为有向边的无向边的指向变为环中点其余点,在此过程中连接的其余点转变为环中点,重复此过程直至所有点转变为环中点,最后剩余的无向边可任意指定方向。

而对于不存在环的连通图,产生的孤立城市数量一定可以且最多可以降至 1 1 1 (方案是构建以某一点为根的树)。所以,答案即为不存在环的连通图的个数。

代码

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;struct DSU
{std::vector<int> f;DSU() {}DSU(int n){init(n);}void init(int n){f.resize(n + 1);std::iota(f.begin() + 1, f.end(), 1);}int find(int x){while (x != f[x]){x = f[x] = f[f[x]];}return x;}bool merge(int x, int y){x = find(x);y = find(y);if (x == y){return false;}f[y] = x;return true;}
};int main()
{ios::sync_with_stdio(0);cin.tie(0);int n, m;cin >> n >> m;DSU dsu = DSU(n);vector<bool> loops(n + 1, 0); // loops[i]为1表示以i为根的并查集有环int x, y;while (m--){cin >> x >> y;bool exist_loop = 0;                                    // 表示x和y合并后的整个并查集是否有环if (loops[dsu.find(x)] == 1 || loops[dsu.find(y)] == 1) // 如果合并前存在环,则合并后依然有环exist_loop = 1;if (dsu.find(x) == dsu.find(y)) // 如果合并前两个点已经在同一个并查集中,那么再加上当前这条边,合并后就能形成环exist_loop = 1;dsu.merge(x, y);if (exist_loop == 1)loops[dsu.find(x)] = 1; // 如果有环,则在根节点打上标记}set<int> st; // set保存各个连通图所在并查集的根节点for (int i = 1; i <= n; i++)st.insert(dsu.find(i));// 答案即为不存在环的连通图的个数int ans = 0;for (auto it = st.begin(); it != st.end(); it++)if (loops[*it] == 0)ans++;cout << ans << '\n';return 0;
}

http://www.ppmy.cn/news/1473700.html

相关文章

【C语言小知识】缓冲区

缓冲区 当我们使用printf()将数据显示在屏幕上&#xff0c;或者使用scanf()函数将数据输入到电脑里&#xff0c;我们是否会产生些许疑问&#xff1f;为何输入的字符会直接显示到屏幕上等等。这里需要介绍一个C语言中的一个关键概念——缓冲区。 当我们使用老式系统进行运行代码…

机器人入门路线及参考资料(机器人操作方向)

机器人入门路线及参考资料&#xff08;机器人操作方向&#xff09; 前言1 数理基础和编程2 机器人学理论3 计算机视觉4 机器人实操5 专攻方向总结Reference: 前言 随着机器人和具身智能时代的到来&#xff0c;机器人越来越受到大家的重视&#xff0c;本文就介绍了机器人&#…

解决Python爬虫开发中的数据输出问题:确保正确生成CSV文件

引言 在大数据时代&#xff0c;爬虫技术成为获取和分析网络数据的重要工具。然而&#xff0c;许多开发者在使用Python编写爬虫时&#xff0c;常常遇到数据输出问题&#xff0c;尤其是在生成CSV文件时出错。本文将详细介绍如何解决这些问题&#xff0c;并提供使用代理IP和多线程…

在原有的iconfont.css文件中加入新的字体图标

前言&#xff1a;在阿里图标库中&#xff0c;如果你没有这个字体图标的线上项目&#xff0c;那么你怎么在本地项目中的原始图标文件中添加新的图标呢&#xff1f; 背景&#xff1a;现有一个vue项目&#xff0c;下面是这个前端项目的字体图标文件。现在需要新开发功能页&#x…

Python实战,桌面小游戏,剪刀石头布

注意:本文的下载教程,与以下文章的思路有相同点,也有不同点,最终目标只是让读者从多维度去熟练掌握本知识点。 下载教程: Python项目开发实战_桌面小游戏-剪刀石头布_编程案例解析实例详解课程教程.pdf 创建一个基于Python的桌面小游戏“剪刀石头布”是一个很好的编程实践…

竞赛选题 交通目标检测-行人车辆检测流量计数 - 竞赛选题

文章目录 0 前言1\. 目标检测概况1.1 什么是目标检测&#xff1f;1.2 发展阶段 2\. 行人检测2.1 行人检测简介2.2 行人检测技术难点2.3 行人检测实现效果2.4 关键代码-训练过程 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 毕业设计…

解决 MEX 文件 ‘xxx.mexw64‘ 无效: 找不到指定的模块。的问题

1.问题描述 在matlab R2021b中运行编译好后的gptoolbox工具箱中的函数[SVtemp,SFtemp,IF] selfintersect(V,F);报错如下 MEX 文件 E:\MATLAB_File\gptoolbox\mex\selfintersect.mexw64 无效: 找不到指定的模块。出错 offset_bunny (第 15 行) [SVtemp,SFtemp,IF] selfinter…

SpringBoot:集成机器学习模型进行预测和分析

引言 机器学习在现代应用程序中扮演着越来越重要的角色。通过集成机器学习模型&#xff0c;开发者可以实现智能预测和数据分析&#xff0c;从而提高应用程序的智能化水平。SpringBoot作为一个强大的框架&#xff0c;能够方便地集成机器学习模型&#xff0c;并提供灵活的部署和…