浅谈基础的图算法——强联通分量算法(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环境,让你在…...

手机三要素接口怎么对接呢?(一)
一、什么是手机三要素? 手机三要素又叫运营商三要素,运营商实名认证,运营商实名核验,手机三要素实名验证,手机三要素实名核验,每个人的称呼都不同,但是入参和出参是一样的。 输入姓名、身份证…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
pam_env.so模块配置解析
在PAM(Pluggable Authentication Modules)配置中, /etc/pam.d/su 文件相关配置含义如下: 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块,负责验证用户身份&am…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...
Linux系统部署KES
1、安装准备 1.版本说明V008R006C009B0014 V008:是version产品的大版本。 R006:是release产品特性版本。 C009:是通用版 B0014:是build开发过程中的构建版本2.硬件要求 #安全版和企业版 内存:1GB 以上 硬盘…...
离线语音识别方案分析
随着人工智能技术的不断发展,语音识别技术也得到了广泛的应用,从智能家居到车载系统,语音识别正在改变我们与设备的交互方式。尤其是离线语音识别,由于其在没有网络连接的情况下仍然能提供稳定、准确的语音处理能力,广…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合
作者:来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布,Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明,Elastic 作为 …...