浅谈基础的图算法——强联通分量算法(c++)
文章目录
- 强联通分量SCC
- 概念
- 例子
- 有向图的DFS树
- 代码
- 例题讲解
- [POI2008] BLO-Blockade
- 题面翻译
- 题目描述
- 输入格式
- 输出格式
- 样例 #1
- 样例输入 #1
- 样例输出 #1
- 思路
- AC代码
- 【模板】割点(割顶)
- 题目背景
- 题目描述
- 输入格式
- 输出格式
- 样例 #1
- 样例输入 #1
- 样例输出 #1
- 提示
- 思路
- AC代码
强联通分量SCC
SCC之前也有写博客讲解
戳这里
概念
- 在有向图中, 如果两个点 u, v 满足同时存在从 u 到 v 和从 v 到 u 的路径, 则称两个点强连通
- 如果有向图任意两个点强连通, 则称为强连通图. 有向图的极大强连通子图称为强连通分量
- 注意到强连通关系是传递的,所以有向图可以划分为若干不交的强连通分量
例子

有向图的DFS树



代码
下面展示的是洛谷模板 缩点一题的代码
包含强联通分量和拓扑排序两部分
#include<bits/stdc++.h>
using namespace std;
const int N=10000+15;
int n,m,idx,timestap,top,s;
int p[N],head[N],sd[N],dfn[N],low[N];
int sta[N],vis[N];
int h[N],in[N],dist[N];
struct T
{int to;int ne;int fr;
}edge[N*10],ed[N*10];
void add(int x,int y)
{edge[++idx].ne=head[x];edge[idx].fr=x;edge[idx].to=y;head[x]=idx;
}
void tarjan(int x)
{low[x]=dfn[x]=++timestap;sta[++top]=x;vis[x]=1;for (int i=head[x];i;i=edge[i].ne){int v=edge[i].to;if (!dfn[v]) {tarjan(v);low[x]=min(low[x],low[v]);}else if (vis[v]){low[x]=min(low[x],low[v]);}}if (dfn[x]==low[x]){int y;while (y=sta[top--]){sd[y]=x;vis[y]=0;if (x==y) break;p[x]+=p[y];}}
}
int topo()
{queue <int> q;int tot=0;for (int i=1;i<=n;i++)if (sd[i]==i&&!in[i]){q.push(i);dist[i]=p[i];} while (!q.empty()){int k=q.front();q.pop();for (int i=h[k];i;i=ed[i].ne){int v=ed[i].to;dist[v]=max(dist[v],dist[k]+p[v]);in[v]--;if (in[v]==0) q.push(v);}}int ans=0;for (int i=1;i<=n;i++)ans=max(ans,dist[i]);return ans;
}
int main()
{scanf("%d%d",&n,&m);for (int i=1;i<=n;i++)scanf("%d",&p[i]);int u,v;for (int i=1;i<=m;i++){scanf("%d%d",&u,&v);add(u,v);}for (int i=1;i<=n;i++)if(!dfn[i])tarjan(i);for (int i=1;i<=m;i++){int x=sd[edge[i].fr],y=sd[edge[i].to];if (x!=y){ed[++s].ne=h[x];ed[s].to=y;ed[s].fr=x;h[x]=s;in[y]++;}}int ans=topo();printf("%d\n",ans);return 0;
}
例题讲解
[POI2008] BLO-Blockade
题面翻译
B 城有 n n n 个城镇, m m m 条双向道路。
每条道路连结两个不同的城镇,没有重复的道路,所有城镇连通。
把城镇看作节点,把道路看作边,容易发现,整个城市构成了一个无向图。
请你对于每个节点 i i i 求出,把与节点 i i i 关联的所有边去掉以后(不去掉节点 i i i 本身),无向图有多少个有序点 ( x , y ) (x,y) (x,y),满足 x x x 和 y y y 不连通。
【输入格式】
第一行包含两个整数 n n n 和 m m m。
接下来 m m m 行,每行包含两个整数 a a a 和 b b b,表示城镇 a a a 和 b b b 之间存在一条道路。
【输出格式】
输出共 n n n 行,每行输出一个整数。
第 i i i 行输出的整数表示把与节点 i i i 关联的所有边去掉以后(不去掉节点 i i i 本身),无向图有多少个有序点 ( x , y ) (x,y) (x,y),满足 x x x 和 y y y 不连通。
【数据范围】
n ≤ 100000 n\le 100000 n≤100000, m ≤ 500000 m\le500000 m≤500000
题目描述
There are exactly n n n towns in Byteotia.
Some towns are connected by bidirectional roads.
There are no crossroads outside towns, though there may be bridges, tunnels and flyovers. Each pair of towns may be connected by at most one direct road. One can get from any town to any other-directly or indirectly.
Each town has exactly one citizen.
For that reason the citizens suffer from loneliness.
It turns out that each citizen would like to pay a visit to every other citizen (in his host’s hometown), and do it exactly once. So exactly n ⋅ ( n − 1 ) n\cdot (n-1) n⋅(n−1) visits should take place.
That’s right, should.
Unfortunately, a general strike of programmers, who demand an emergency purchase of software, is under way.
As an act of protest, the programmers plan to block one town of Byteotia, preventing entering it, leaving it, and even passing through.
As we speak, they are debating which town to choose so that the consequences are most severe.
Task Write a programme that:
reads the Byteotian road system’s description from the standard input, for each town determines, how many visits could take place if this town were not blocked by programmers, writes out the outcome to the standard output.
给定一张无向图,求每个点被封锁之后有多少个有序点对(x,y)(x!=y,1<=x,y<=n)满足x无法到达y
输入格式
In the first line of the standard input there are two positive integers: n n n and m m m ( 1 ≤ n ≤ 100 000 1\le n\le 100\ 000 1≤n≤100 000, 1 ≤ m ≤ 500 000 1\le m\le 500\ 000 1≤m≤500 000) denoting the number of towns and roads, respectively.
The towns are numbered from 1 to n n n.
The following m m m lines contain descriptions of the roads.
Each line contains two integers a a a and b b b ( 1 ≤ a < b ≤ n 1\le a<b\le n 1≤a<b≤n) and denotes a direct road between towns numbered a a a and b b b.
输出格式
Your programme should write out exactly n n n integers to the standard output, one number per line. The i t h i^{th} ith line should contain the number of visits that could not take place if the programmers blocked the town no. i i i.
样例 #1
样例输入 #1
5 5
1 2
2 3
1 3
3 4
4 5
样例输出 #1
8
8
16
14
8
思路
魔改一下 tarjan 求割点的过程。

AC代码
#include<bits/stdc++.h>
using namespace std;
const int N=1000010;
int n,m,h[N],idx;
int dfn[N],low[N],siz[N],tot;
long long ans[N];
bool cut[N];
int e[N],ne[N];
inline void add(int u,int v){e[++idx]=v;ne[idx]=h[u];h[u]=idx;
}
void tarjan(int u){dfn[u]=low[u]=++tot;siz[u]=1;int flag=0,sum=0;for(int i=h[u];i;i=ne[i]){int v=e[i];if(!dfn[v]){tarjan(v);siz[u]+=siz[v];low[u]=min(low[u],low[v]);if(low[v]>=dfn[u]){ans[u]+=(long long)siz[v]*(n-siz[v]);sum+=siz[v];flag++;if(u!=1||flag>1) cut[u]=true;}}else low[u]=min(low[u],dfn[v]);}if(!cut[u]) ans[u]=2*(n-1);else ans[u]+=(long long)(n-sum-1)*(sum+1)+(n-1);
}
int main(){ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n>>m;for(int i=1;i<=m;i++){int x,y;cin>>x>>y;add(x,y);add(y,x);}tarjan(1);for(int i=1;i<=n;i++)cout<<ans[i]<<endl;return 0;
}
【模板】割点(割顶)
题目背景
割点
题目描述
给出一个 n n n 个点, m m m 条边的无向图,求图的割点。
输入格式
第一行输入两个正整数 n , m n,m n,m。
下面 m m m 行每行输入两个正整数 x , y x,y x,y 表示 x x x 到 y y y 有一条边。
输出格式
第一行输出割点个数。
第二行按照节点编号从小到大输出节点,用空格隔开。
样例 #1
样例输入 #1
6 7
1 2
1 3
1 4
2 5
3 5
4 5
5 6
样例输出 #1
1
5
提示
对于全部数据, 1 ≤ n ≤ 2 × 1 0 4 1\leq n \le 2\times 10^4 1≤n≤2×104, 1 ≤ m ≤ 1 × 1 0 5 1\leq m \le 1 \times 10^5 1≤m≤1×105。
点的编号均大于 0 0 0 小于等于 n n n。
tarjan图不一定联通。
思路
个点就是去掉这个点之后,图中的强联通分量变多了,那么这个点就是一个割点
因为这样,假设割点左边有一个子图,右边也有一个子图,由于这个点是割点,那么左右一定是没有其他边联通的, 所以该点的联通的连v满足low[v]>=dfn[u],最后特判一下根
AC代码
#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
vector<int> g[N<<1];
int n,m,ind[N],low[N],dfn[N],ans,s,ans1[N],tot,num,cut[N],vis[N],now,root;
void tarjan(int u){low[u]=dfn[u]=++now,vis[u]=1;for(int i=0;i<g[u].size();i++){int v=g[u][i];if(!dfn[v]){tarjan(v);if(u==root) s++;else{low[u]=min(low[u],low[v]);if(low[v]>=dfn[u]) cut[u]=1;}}elselow[u]=min(low[u],dfn[v]);}
}
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);cin>>n>>m;for(int i=1,u,v;i<=m;i++){cin>>u>>v;g[u].push_back(v);g[v].push_back(u);}for(int i=1;i<=n;i++){s=0;if(dfn[i]) continue;root=i,now=0;tarjan(i);ind[i]=s; } for(int i=1;i<=n;i++)if(ind[i]>1)ans1[++tot]=i;for(int i=1;i<=n;i++){ if(ind[i]!=0)continue;if(cut[i]==1)ans1[++tot]=i;}sort(ans1+1,ans1+tot+1);cout<<tot<<endl;for(int i=1;i<=tot;i++) cout<<ans1[i]<<" ";
}
这是我的第二十二篇文章,如有纰漏也请各位大佬指正
辛苦创作不易,还望看官点赞收藏打赏,后续还会更新新的内容。
相关文章:
浅谈基础的图算法——强联通分量算法(c++)
文章目录 强联通分量SCC概念例子有向图的DFS树代码例题讲解[POI2008] BLO-Blockade题面翻译题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 思路AC代码 【模板】割点(割顶)题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示…...
C#:通用方法总结—第13集
大家好,今天继续讲解我们的通用方法系列。 下面是今天要介绍的通用方法: (1)这个通用方法为ug获取选择圆边的圆心 /// <summary> /// ug获取选择圆边的圆心 /// </summary> /// <param name"a">&l…...
AI答题应用平台相关面试题
目录 1、请介绍整个系统后端的架构设计,有哪些模块以及各模块之间的关系? 2、你在项目中是如何设计库表的?可以从字段、索引、关联等方面回答。 3、为什么使用策略模式来封装不同的应用评分算法?它有哪些好处?具体如…...
树莓派NAS系统搭建教程:使用Flask和SQLite实现HTTP/HTTPS文件管理(代码示例)
一、项目概述 随着物联网(IoT)技术的发展,数据存储和共享需求日益增长。本文将介绍如何利用树莓派(Raspberry Pi)搭建一个网络附加存储(NAS)系统,以实现数据的集中管理、共享和访问…...
mysql如何储存大量数据,分库存分表的建议和看法
MySQL 在处理大量数据时,分库分表是常见的策略,可以有效提升数据库的性能和扩展性。下面是关于 MySQL 分库分表的建议和看法: 1. 何时考虑分库分表 数据量大:当单一数据库实例无法处理大规模数据或达到性能瓶颈时,可以…...
Golang | Leetcode Golang题解之第310题最小高度树
题目: 题解: func findMinHeightTrees(n int, edges [][]int) []int {if n 1 {return []int{0}}g : make([][]int, n)deg : make([]int, n)for _, e : range edges {x, y : e[0], e[1]g[x] append(g[x], y)g[y] append(g[y], x)deg[x]deg[y]}q : []i…...
【面试系列】软件架构师 高频面试题及详细解答
欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题. ⭐️ AIGC时代的创新与未来:详细讲解AIGC的概念、核心技术、应用领域等内容。 ⭐…...
二百五十四、OceanBase——Linux上安装OceanBase数据库(四):登录ocp-express,配置租户管理等信息
一、目的 在部署OceanBase成功后,接下来就是登录ocp-express,配置租户管理等信息! 二、ocp-express网址以及账密信息 三、实施步骤 1 登录ocp-express 2 集群总览 3 租户管理 3.1 新建租户 3.2 配置新租户信息 剩下的几个模块了解即可&am…...
HCIP学习作业一 | HCIA复习
要求: R1-R2-R3-R4-R5 RIP 100 运行版本2 R6-R7 RIP 200 运行版本1 1.使用合理IP地址规划网络,各自创建环回接口 2.R1创建环回 172.16.1.1/24 172.16.2.1/24 172.16.3.1/24 3.要求R3使用R2访问R1环回 4.减少路由条目数量,R1-R2之间…...
OCR图片矫正、表格检测及裁剪综合实践
问题描述 实际工程中,我们经常需要对图片进行预处理,比如: 1、图片是倾斜的 2、图片背景需要处理掉 3、图片的公章需要剔除 4、图片过暗,过亮 5、图片表格检测 6、图片表格版面分析 。。。。。。等等各种情况。 结果展示…...
c++ 容器 vector
vector的意思就是向量,就是一个顺序表的意思,这个顺序表可以存任意的类型,因为其线性的内存特点,所以在stl里是经常被使用的存在。 vector vector既然要能储存任意的变量,那么就必须使用模板: 这里的T就是变量类型&a…...
零基础部署Minecraft到云服务器上教程
零基础部署Minecraft到云服务器上教程 温馨提示 温馨提示 本教程是由博主个人飞书上直接复制下来,观感较差,请下载本教程对应的pdf资源文件进行查看(在最顶端,不过恳请各位留下一个赞再走吧)。本教程不包含云服务的购…...
常见cms漏洞之dedecms
DedeCMS是织梦团队开发PHP 网站管理系统,它以简单、易用、高效为特色,组建出各种各样各具特色的网站,如地方门户、行业门户、政府及企事业站点等。 下载地址请网上自行寻找 搭建方式选择php study 首先搭建环境 #前台http://localhost/dedecm…...
深入探究Liunx服务器内存:模拟程序实际占用与缓存占用内存
文章目录 深入探究Liunx服务器内存:模拟程序实际占用与缓存占用内存实际内存占用:使用 memtester安装 memtester下载和编译安装 memtester 使用 memtester 缓存占用:使用虚拟内存构造内存消耗创建虚拟内存目录挂载虚拟内存创建大文件以消耗内…...
《Milvus Cloud向量数据库指南》——Zilliz Cloud 高可用性深度解析:赋能GenAI应用,引领非结构化数据新纪元
在人工智能与大数据技术日新月异的今天,非结构化数据的处理与分析已成为推动行业智能化转型的关键驱动力。Zilliz Cloud,作为基于开源向量数据库Milvus构建的全托管解决方案,不仅革新了非结构化数据的存储与查询方式,更以其卓越的高可用性设计,为开发人员构建高效、可靠的…...
2024/8/4 维高-STD60N驱动器(伺服)---客户反馈:电机异响
步进电机 MHS1A86-60B85B ,额定电流6A 步骤一:设置额定电流 std60n驱动器拔码全部为off(后台设置),伺服后台连上后设置h00-11按电机铭牌进行 设置下额定电流 步骤二:最好设置峰值电流一…...
驾驭RESTful海洋:在PyCharm中配置和使用REST客户端全攻略
标题:驾驭RESTful海洋:在PyCharm中配置和使用REST客户端全攻略 引言 在当今的软件开发中,REST(Representational State Transfer)API已成为前后端分离架构的核心组成部分。PyCharm,作为业界领先的集成开发…...
策略模式的一次应用
项目的需求是将一组图像按照相似度分类。 采用了模板匹配计算相似度的实现方式。 #include <opencv2/core.hpp> #include <openev2/core/utility.hpp> #include <opencv2/highqui.hpp> #include <openav2/imgproc.hpp> cv::Mat image matched; double …...
探索PyCharm的C/C++支持:一站式配置指南
探索PyCharm的C/C支持:一站式配置指南 引言 PyCharm,作为JetBrains家族中的一个强大IDE,以其对Python的卓越支持而闻名。然而,PyCharm的多语言支持同样不容小觑。本文将带领你了解如何在PyCharm中配置C/C环境,让你在…...
手机三要素接口怎么对接呢?(一)
一、什么是手机三要素? 手机三要素又叫运营商三要素,运营商实名认证,运营商实名核验,手机三要素实名验证,手机三要素实名核验,每个人的称呼都不同,但是入参和出参是一样的。 输入姓名、身份证…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南
精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南 在数字化营销时代,邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天,我们将深入解析邮件打开率、网站可用性、页面参与时…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
