acwing算法提高之图论--无向图的双连通分量

目录

  • 1 介绍
  • 2 训练

1 介绍

本博客用来记录无向图的双连通分量的相关题目。

以下所有概念都是针对无向图而言的。
:本质是边,去掉它,图就不连通了。这样的边叫作桥。
边双连通分量:不包含桥的连通块,且边的数目最大。

割点:本质是结点,去掉它(即去掉这个结点和它所关联的边),图就不连通了。这样的结点叫作割点。
点双连通分量:不包含割点的连通块,且结点的数目最大。

边双连通分量的求解方法:引入时间戳,与有向图强连通分量的求解方法类似。

结论1:对于有向图,至少需要加多少条边,能将此图变成一个强连通分量。答案是max(p, q),其中p是起点个数(即入度为0的结点个数),q是终点个数(即出度为0的结点个数)。

结论2:对于无向图,至少需要加入多少条边,能将此图变成一个边双连通分量。答案是(cnt + 1) / 2。其中cnt是指出度和入度皆为为1的结点数目。

点双连通分量的求解方法

2 训练

题目1:395冗余路径

C++代码如下,

#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 5010, M = 20010;int n, m;
int h[N], e[M], ne[M], idx;
int dfn[N], low[N], timestamp;
int stk[N], top;
int id[N], dcc_cnt;
bool is_bridge[M];
int d[N];void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}void tarjan(int u, int from) {dfn[u] = low[u] = ++timestamp;stk[++top] = u;for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (!dfn[j]) {tarjan(j, i);low[u] = min(low[u], low[j]);if (dfn[u] < low[j]) {is_bridge[i] = is_bridge[i ^ 1] = true;}} else if (i != (from ^ 1)) {low[u] = min(low[u], dfn[j]);}}if (dfn[u] == low[u]) {++dcc_cnt;int y;do {y = stk[top--];id[y] = dcc_cnt;} while (y != u);}
}int main() {cin >> n >> m;memset(h, -1, sizeof h);while (m--) {int a, b;cin >> a >> b;add(a, b), add(b, a);}tarjan(1, -1);for (int i = 0; i < idx; ++i) {if (is_bridge[i]) {d[id[e[i]]]++;}}int cnt = 0;for (int i = 1; i <= dcc_cnt; ++i) {if (d[i] == 1) {cnt++;}}printf("%d\n", (cnt + 1) / 2);return 0;
}

题目2:1183电力

C++代码如下,

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>using namespace std;const int N = 10010, M = 30010;int n, m;
int h[N], e[M], ne[M], idx;
int dfn[M], low[N], timestamp;
int root, ans;void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}void tarjan(int u) {dfn[u] = low[u] = ++timestamp;int cnt = 0;for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (!dfn[j]) {tarjan(j);low[u] = min(low[u], low[j]);if (low[j] >= dfn[u]) cnt++;} else {low[u] = min(low[u], dfn[j]);}}if (u != root) cnt++;ans = max(ans, cnt);return;
}int main() {while (scanf("%d%d", &n, &m), n || m) {memset(dfn, 0, sizeof dfn);memset(h, -1, sizeof h);idx = timestamp = 0;while (m--) {int a, b;scanf("%d%d", &a, &b);add(a, b), add(b, a);}ans = 0;int cnt = 0;for (root = 0; root < n; root++) {if (!dfn[root]) {cnt++;tarjan(root);}}printf("%d\n", ans + cnt - 1);}return 0;
}

题目3:396矿场搭建

C++代码如下,

#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>using namespace std;typedef unsigned long long ULL;const int N = 1010, M = 1010;int n, m;
int h[N], e[M], ne[M], idx;
int dfn[N], low[N], timestamp;
int stk[N], top;
int dcc_cnt;
vector<int> dcc[N];
bool cut[N];
int root;void add(int a, int b) {e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}void tarjan(int u) {dfn[u] = low[u] = ++ timestamp;stk[++top] = u;if (u == root && h[u] == -1) {dcc_cnt ++;dcc[dcc_cnt].push_back(u);return;}int cnt = 0;for (int i = h[u]; ~i; i = ne[i]) {int j = e[i];if (!dfn[j]) {tarjan(j);low[u] = min(low[u], low[j]);if (dfn[u] <= low[j]) {cnt++;if (u != root || cnt > 1) cut[u] = true;++dcc_cnt;int y;do {y = stk[top--];dcc[dcc_cnt].push_back(y);} while (y != j);dcc[dcc_cnt].push_back(u);}} else {low[u] = min(low[u], dfn[j]);}}
}int main() {int T = 1;while (cin >> m, m) {for (int i = 1; i <= dcc_cnt; ++i) dcc[i].clear();idx = n = timestamp = top = dcc_cnt = 0;memset(h, -1, sizeof h);memset(dfn, 0, sizeof dfn);memset(cut, 0, sizeof cut);while (m--) {int a, b;cin >> a >> b;n = max(n, a), n = max(n, b);add(a, b), add(b, a);}for (root = 1; root <= n; ++root) {if (!dfn[root]) {tarjan(root);}}int res = 0;ULL num = 1;for (int i = 1; i <= dcc_cnt; ++i) {int cnt = 0;for (int j = 0; j < dcc[i].size(); ++j) {if (cut[dcc[i][j]]) {cnt++;}}if (cnt == 0) {if (dcc[i].size() > 1) res += 2, num *= dcc[i].size() * (dcc[i].size() - 1) / 2;else res++;} else if (cnt == 1) res++, num *= dcc[i].size() - 1;}printf("Case %d: %d %llu\n", T++, res, num);}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/1166.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux驱动开发——(一)设备树的基本属性及其应用

目录 一、常见基本属性 1.1 compatible属性 1.2 status属性 1.3 reg属性 1.4 #address-cells属性和#size-cells属性 二、基本属性在设备树的表现 三、基本属性在驱动代码的表现 3.1 驱动代码 3.2 驱动代码中的OF函数 3.2.1 of_find_node_by_path 3.2.2 of_find_prope…

通往大厂之路:Solr面试题及参考答案100道题

目录 什么是Solr,它主要用来做什么? 解释Solr和Lucene的关系。 Solr有哪些主要特点?

Python基本数据结构和常见算法

Python 中的基本算法包括各种数据结构的实现和常见算法的应用。以下是 Python 中常见的基本算法及其简要介绍&#xff1a; ### 数据结构 1. **列表&#xff08;List&#xff09;**&#xff1a; - Python 中内置的基本数据结构&#xff0c;支持动态数组的操作&#xff0c;可…

Unity类银河恶魔城学习记录13-5,6 p146 Delete save file,p147 Encryption of saved data源代码

Alex教程每一P的教程原代码加上我自己的理解初步理解写的注释&#xff0c;可供学习Alex教程的人参考 此代码仅为较上一P有所改变的代码 【Unity教程】从0编程制作类银河恶魔城游戏_哔哩哔哩_bilibili FileDataHandler.cs using System; using System.IO; using UnityEngine; p…

多态的底层实现原理

简述一下多态的底层实现原理 在面向对象编程中&#xff0c;多态是一个核心概念&#xff0c;它允许使用父类类型的指针或引用来引用子类对象&#xff0c;并通过这种方式实现在运行时选择适当的方法。本文将深入探讨多态的底层实现原理&#xff0c;包括虚函数、虚函数表、派生类…

Spring Boot + Thymeleaf 实现的任务发布网站

角色&#xff1a; 管理员雇主雇员 功能 雇主&#xff1a;登录、注册、发布任务、选择中标雇员、评价雇员雇员&#xff1a;登录、注册、查看任务列表、投标任务、收藏任务、完成任务管理员、登录、任务管理、雇主管理、雇员管理 部分功能截图 部署 导入数据库…

.NET 邮件发送 SMTP邮件发送

SMTP&#xff08;Simple Mail Transfer Protocol&#xff09;是用于电子邮件传输的规则集&#xff0c;可以从邮件客户端向接收电子邮件服务器发送、中继或转发邮件。发件人可使用SMTP 服务器来执行发送电子邮件的过程。SMTP服务器则是按照这些规则中转电子邮件的服务器。 IMAP…

视频质量评价 PSNR 算法详细介绍

PSNR PSNR(Peak Signal-to-Noise Ratio,峰值信噪比)是一种常用的评价图像质量的指标,尤其在图像压缩和图像处理领域。它基于最大可能的图像信号功率和图像的噪声功率之间的比率,通常用于衡量图像恢复或图像压缩算法的效果。 原理 PSNR是基于MSE(Mean Squared Error,均…

node-sass报错

node-sass报错 解决方案 有几种解决方案&#xff0c;但感觉都是为了下载vsta_sdk这个工具的。 有的电脑下载C开发程序时可以顺带下载这个插件。 可以直接下载VS之后点击下载C桌面开发&#xff0c;但是有的不行&#xff0c;所以网上也就有另外一种方式&#xff0c;就是下载V…

C# danbooru Stable Diffusion 提示词反推 OpenVINO Demo

C# danbooru Stable Diffusion 提示词反推 OpenVINO Demo 目录 说明 效果 模型信息 项目 代码 下载 说明 模型下载地址&#xff1a;https://huggingface.co/deepghs/ml-danbooru-onnx 效果 模型信息 OVVersion { BuildNumber 2023.1.0-12185-9e6b00e51cd-releases/20…

桌面软件使用到的开源库

想了解一下桌面软件开发中可能使用到的dll库 联想锁屏 libcef-常用概念-框架特点-CSDN博客 libcurl库使用详情、libcurl库的制作-CSDN博客 使用Cef和Qt做一个跨平台的多标签多窗口浏览器_cef3 多个标签-CSDN博客 cef 依赖的文件 libcef - Bigben - 博客园 (cnblogs.com) Q…

Hikyuu 2.0.2 发布,高性能量化交易研究框架

新增特性 历史财务信息入库&#xff0c;对于使用 MySQL 存储&#xff0c;可以直接使用服务端的财务数据&#xff08;之前只能在执行数据下载的机器上获取&#xff09;增加指标 FINANCE 获取相应历史财务数据&#xff0c;具体财务字段信息可通过StockManager.get_history_finan…

Android AIDL接口

一.AlDI接口简介 AIDL&#xff08;Android Interface Definition Language&#xff09;是一种 IDL 语言&#xff0c;用于生成可以在 Android 设备上两个进程之间进行进程间通信&#xff08;IPC&#xff09;的代码。 通过 AIDL&#xff0c;可以在一个进程中获取另一个进程的数据…

开源博客项目Blog .NET Core源码学习(16:App.Hosting项目结构分析-4)

本文学习并分析App.Hosting项目中前台页面的文章专栏页面和文章详情页面。< 文章专栏页面 文章专栏页面总体上为左右布局&#xff0c;左侧显示文章列表&#xff0c;右侧从上向下为关键词搜索、分类导航、热门文章等内容。整个页面使用了layui中的面包屑导航、表单、模版、流…

MySQL数据库外键约束打开与关闭 ️

MySQL数据库外键约束打开与关闭 &#x1f6e0;️ MySQL数据库外键约束打开与关闭 &#x1f6e0;️摘要 &#x1f4dd;引言 &#x1f680;正文内容&#xff08;详细介绍&#xff09; &#x1f4a1;关闭外键约束检查外键约束检查关闭的作用风险与最佳实践建议 &#x1f914; QA环…

使用Spring进行文件的上传和下载

概览 使用Spring进行文件的上传和下载Spring上传文件接口设计dubbo接口设计上传文件流的RPC的接口设计 Spring文件下载接口设计dubbo接口设计下载文件流的RPC的接口设计 spring上传文件大小控制 使用Spring进行文件的上传和下载 本文主要介绍在Spring框架下面调用微服务的dubb…

LeetCode36: 有效的数独(Java)

题目&#xff1a; 请你判断一个 9 x 9 的数独是否有效。只需要 根据以下规则 &#xff0c;验证已经填入的数字是否有效即可。 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。&#xff08;请参考示例…

vue 性能优化

data 层级不要太深 data 层级太深会增加响应式监听的计算&#xff0c;导致页面初次渲染时卡顿。 合理使用 v-show 和 v-if 频繁切换时&#xff0c;使用 v-show无需频繁切换时&#xff0c;使用 v-if 合理使用 computed computed 有缓存&#xff0c;data 不变时不会重新计算&…

一次Ambari安装记录

引言 Ambari是一个开源的Apache项目,它提供了一个直观易用的Web界面,用于管理、监控和配置Apache Hadoop集群。它是一个集群管理工具,可以帮助管理员轻松地部署、管理和监控Hadoop集群的各种组件,如HDFS、YARN、MapReduce、Hive、HBase等。通过Ambari,用户可以在集群中添…

pwn程序已经运行了,payload字节数组包含不可见字符,无法进行utf8编码,这个时候怎么输入?

假设./your_elf_program已经运行了,payload字节数组包含不可见字符,无法进行utf8编码,这个时候怎么输入? 如果 ./your_elf_program 已经在运行,并且你需要发送包含不可见字符的 payload 字节数组,你不能直接通过常规的命令行输入,因为终端不支持非 UTF-8 编码的数据输入…