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

devtools/2024/11/13 9:01:22/

目录

  • 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.ppmy.cn/devtools/6497.html

相关文章

速盾:cdn可以加速哪些服务器

CDN&#xff08;Content Delivery Network&#xff0c;内容分发网络&#xff09;是一种通过将网站的静态资源部署到全球各地的服务器上&#xff0c;以提供更快速、更可靠的访问体验的技术。CDN可以加速许多类型的服务器&#xff0c;包括但不限于以下几种&#xff1a; 静态资源服…

【考研高数】学习笔记分享

派大星说数学&#xff08;导学部分&#xff09; 关于做题 测试 答疑阶段 直播 群内 高中基础知识导学 一、数与式 述了课程学习和因式分解、分式拆解等知识点。学生应了解课程内容&#xff0c;带着疑问听课&#xff0c;不要抄笔记&#xff0c;导学课和基础课都有测验&…

Java,Python和Go语言语法差异对比

前段时间一直在找工作&#xff0c;比较颓废&#xff0c;很长时间都没有更新博客了&#xff0c;最近公司的项目需要用到Python语言和Go语言&#xff0c; 所以又重新学习了一下Python语言和Go语言&#xff0c;现在做一些总结&#xff0c;方便以后复习使用&#xff0c;同时也给其他…

web大型工程项目架构以及搭建

一、项目结构 ├── public/ ├── config/ │ └── proxy.js # 本地代理配置 ├── src/ │ ├── assets/ │ ├── components/ │ ├── configs/ │ │ ├── index.js # 应用配置 │ │ ├…

什么是0-day漏洞,怎么防护0-day漏洞攻击

随着信息技术的快速发展&#xff0c;网络安全问题日益凸显&#xff0c;其中0day漏洞攻击作为一种高级威胁手段&#xff0c;给企业和个人用户带来了极大的风险。下面德迅云安全就对0day漏洞攻击进行简单讲解下&#xff0c;并分享相应的一些安全措施&#xff0c;以期提高网络安全…

XiaodiSec day033 Learn Note 小迪渗透学习笔记

XiaodiSec day033 Learn Note 小迪渗透学习笔记 记录得比较凌乱&#xff0c;不尽详细 day33 文件上传 中间件上传&#xff0c;学了也不一定遇得到&#xff0c;但是要学 文件上传漏洞有几个情况会导致&#xff0c;有后端验证&#xff0c;第三方富文本编辑器导致 编辑器被目…

【Vue】Vue中使一个div铺满全屏

在Vue中实现div全屏铺满的方式与纯CSS实现类似&#xff0c;只是在Vue组件中应用CSS的方式略有不同。 最近在项目开发中&#xff0c;就遇到了这个问题&#xff0c;特此记录一下&#xff0c;方便大伙避坑。 有这么一段代码&#xff1a; <template><div class"fu…

HTML部分常用标签补充

table&#xff08;布局方面不建议使用&#xff0c;而是使用CSS来完成&#xff09;: 标签解释&#xff1a; ~table标签顾名思义&#xff0c;是表格的意思 ~table其中可以使用boder属性来显示表格的线&#xff0c;最好使用CSS来配合HTML的使用 ~table内的内容可以使用colspan来定…