当前位置: 首页 > news >正文

浅谈基础的图算法——强联通分量算法(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 n100000 m ≤ 500000 m\le500000 m500000

题目描述

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(n1) 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 1n100 000, 1 ≤ m ≤ 500 000 1\le m\le 500\ 000 1m500 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 1a<bn) 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 1n2×104 1 ≤ m ≤ 1 × 1 0 5 1\leq m \le 1 \times 10^5 1m1×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代码 【模板】割点&#xff08;割顶&#xff09;题目背景题目描述输入格式输出格式样例 #1样例输入 #1样例输出 #1 提示…...

C#:通用方法总结—第13集

大家好&#xff0c;今天继续讲解我们的通用方法系列。 下面是今天要介绍的通用方法&#xff1a; &#xff08;1&#xff09;这个通用方法为ug获取选择圆边的圆心 /// <summary> /// ug获取选择圆边的圆心 /// </summary> /// <param name"a">&l…...

AI答题应用平台相关面试题

目录 1、请介绍整个系统后端的架构设计&#xff0c;有哪些模块以及各模块之间的关系&#xff1f; 2、你在项目中是如何设计库表的&#xff1f;可以从字段、索引、关联等方面回答。 3、为什么使用策略模式来封装不同的应用评分算法&#xff1f;它有哪些好处&#xff1f;具体如…...

树莓派NAS系统搭建教程:使用Flask和SQLite实现HTTP/HTTPS文件管理(代码示例)

一、项目概述 随着物联网&#xff08;IoT&#xff09;技术的发展&#xff0c;数据存储和共享需求日益增长。本文将介绍如何利用树莓派&#xff08;Raspberry Pi&#xff09;搭建一个网络附加存储&#xff08;NAS&#xff09;系统&#xff0c;以实现数据的集中管理、共享和访问…...

mysql如何储存大量数据,分库存分表的建议和看法

MySQL 在处理大量数据时&#xff0c;分库分表是常见的策略&#xff0c;可以有效提升数据库的性能和扩展性。下面是关于 MySQL 分库分表的建议和看法&#xff1a; 1. 何时考虑分库分表 数据量大&#xff1a;当单一数据库实例无法处理大规模数据或达到性能瓶颈时&#xff0c;可以…...

Golang | Leetcode Golang题解之第310题最小高度树

题目&#xff1a; 题解&#xff1a; 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成功后&#xff0c;接下来就是登录ocp-express&#xff0c;配置租户管理等信息&#xff01; 二、ocp-express网址以及账密信息 三、实施步骤 1 登录ocp-express 2 集群总览 3 租户管理 3.1 新建租户 3.2 配置新租户信息 剩下的几个模块了解即可&am…...

HCIP学习作业一 | HCIA复习

要求&#xff1a; R1-R2-R3-R4-R5 RIP 100 运行版本2 R6-R7 RIP 200 运行版本1 1.使用合理IP地址规划网络&#xff0c;各自创建环回接口 2.R1创建环回 172.16.1.1/24 172.16.2.1/24 172.16.3.1/24 3.要求R3使用R2访问R1环回 4.减少路由条目数量&#xff0c;R1-R2之间…...

OCR图片矫正、表格检测及裁剪综合实践

问题描述 实际工程中&#xff0c;我们经常需要对图片进行预处理&#xff0c;比如&#xff1a; 1、图片是倾斜的 2、图片背景需要处理掉 3、图片的公章需要剔除 4、图片过暗&#xff0c;过亮 5、图片表格检测 6、图片表格版面分析 。。。。。。等等各种情况。 结果展示…...

c++ 容器 vector

vector的意思就是向量&#xff0c;就是一个顺序表的意思&#xff0c;这个顺序表可以存任意的类型&#xff0c;因为其线性的内存特点&#xff0c;所以在stl里是经常被使用的存在。 vector vector既然要能储存任意的变量&#xff0c;那么就必须使用模板: 这里的T就是变量类型&a…...

零基础部署Minecraft到云服务器上教程

零基础部署Minecraft到云服务器上教程 温馨提示 温馨提示 本教程是由博主个人飞书上直接复制下来&#xff0c;观感较差&#xff0c;请下载本教程对应的pdf资源文件进行查看&#xff08;在最顶端&#xff0c;不过恳请各位留下一个赞再走吧&#xff09;。本教程不包含云服务的购…...

常见cms漏洞之dedecms

DedeCMS是织梦团队开发PHP 网站管理系统&#xff0c;它以简单、易用、高效为特色&#xff0c;组建出各种各样各具特色的网站&#xff0c;如地方门户、行业门户、政府及企事业站点等。 下载地址请网上自行寻找 搭建方式选择php study 首先搭建环境 #前台http://localhost/dedecm…...

深入探究Liunx服务器内存:模拟程序实际占用与缓存占用内存

文章目录 深入探究Liunx服务器内存&#xff1a;模拟程序实际占用与缓存占用内存实际内存占用&#xff1a;使用 memtester安装 memtester下载和编译安装 memtester 使用 memtester 缓存占用&#xff1a;使用虚拟内存构造内存消耗创建虚拟内存目录挂载虚拟内存创建大文件以消耗内…...

《Milvus Cloud向量数据库指南》——Zilliz Cloud 高可用性深度解析:赋能GenAI应用,引领非结构化数据新纪元

在人工智能与大数据技术日新月异的今天,非结构化数据的处理与分析已成为推动行业智能化转型的关键驱动力。Zilliz Cloud,作为基于开源向量数据库Milvus构建的全托管解决方案,不仅革新了非结构化数据的存储与查询方式,更以其卓越的高可用性设计,为开发人员构建高效、可靠的…...

2024/8/4 维高-STD60N驱动器(伺服)---客户反馈:电机异响

步进电机 MHS1A86-60B85B &#xff0c;额定电流6A 步骤一&#xff1a;设置额定电流 std60n驱动器拔码全部为off&#xff08;后台设置&#xff09;&#xff0c;伺服后台连上后设置h00-11按电机铭牌进行 设置下额定电流 步骤二&#xff1a;最好设置峰值电流一…...

驾驭RESTful海洋:在PyCharm中配置和使用REST客户端全攻略

标题&#xff1a;驾驭RESTful海洋&#xff1a;在PyCharm中配置和使用REST客户端全攻略 引言 在当今的软件开发中&#xff0c;REST&#xff08;Representational State Transfer&#xff09;API已成为前后端分离架构的核心组成部分。PyCharm&#xff0c;作为业界领先的集成开发…...

策略模式的一次应用

项目的需求是将一组图像按照相似度分类。 采用了模板匹配计算相似度的实现方式。 #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支持&#xff1a;一站式配置指南 引言 PyCharm&#xff0c;作为JetBrains家族中的一个强大IDE&#xff0c;以其对Python的卓越支持而闻名。然而&#xff0c;PyCharm的多语言支持同样不容小觑。本文将带领你了解如何在PyCharm中配置C/C环境&#xff0c;让你在…...

手机三要素接口怎么对接呢?(一)

一、什么是手机三要素&#xff1f; 手机三要素又叫运营商三要素&#xff0c;运营商实名认证&#xff0c;运营商实名核验&#xff0c;手机三要素实名验证&#xff0c;手机三要素实名核验&#xff0c;每个人的称呼都不同&#xff0c;但是入参和出参是一样的。 输入姓名、身份证…...

状态同步帧同步

帧同步&#xff1a; 有明确的逻辑帧概念&#xff0c;按照固定的逻辑帧间隔同步帧数据 原理 锁帧&#xff1a;mmo那种游戏&#xff0c;服务器需要收到第k帧所有客户端的指令&#xff0c;就算没有操作也发个空指令上去&#xff08;相对来说回合制卡牌这类就简单很多&#xff0…...

Flink 开发语言选择 —— Java vs Scala

引言 Apache Flink 是一个用于处理无界和有界数据流的开源分布式计算框架。随着 Flink 的日益流行&#xff0c;越来越多的开发者开始考虑使用哪种编程语言来进行 Flink 应用程序的开发。本文将探讨在 Flink 中使用 Java 和 Scala 的优缺点&#xff0c;并帮助你做出更明智的选择…...

如何在 Apache Web 服务器中安装、配置和使用模块

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 ## 状态&#xff1a;已弃用本文涵盖的是不再受支持的 Ubuntu 版本。如果您目前正在运行 Ubuntu 12.04 服务器&#xff0c;我们强烈建议升…...

海信聚好看的DBDocter软件使用心得

在墨天轮大会看到这个软件,好称是内核级别的诊断工具, 工作空闲下载免费看看 结果要1.7GB还TAR. DBdoctor是一款内核级数据库性能诊断软件。可以对数据库做细粒度的扫描&#xff0c;帮助您一分钟内找到数据库性能问题&#xff0c;实现性能诊断百倍提效。针对数据库性能诊断门…...

dfs深搜

Problem - C - Codeforces 无向图,判断是否是子叶....

【React】详解 index.js 文件

文章目录 一、index.js文件的基本结构1. 引入必要的模块2. 渲染根组件3. 注册服务工作者&#xff08;可选&#xff09; 二、index.js文件的详细解析1. ReactDOM.render的作用2. 为什么使用React.StrictMode3. 服务工作者的注册 三、index.js文件的最佳实践1. 使用模块化引入2. …...

Android NDK/JNI面试题大全及参考答案(3万字长文)

目录 什么是NDK?它主要用来做什么? 为什么在Android开发中使用NDK? 描述一下NDK和JDK之间的关系 举出一些使用NDK开发的应用场景 什么是JNI?它如何与NDK配合使用? 如何安装和配置Android NDK? 在Android Studio中如何配置NDK路径? 描述一下NDK工具链中的主要工具…...

从根儿上学习spring一 之杂谈

相信学做Java开发的同学从开始工作时就被问及什么是spring的依赖注入&#xff0c;以及切面编程。今天我们简单再聊聊这两个概念。 依赖注入 这里的依赖不是动词依赖依靠的意思&#xff0c;而是名词。可以把这两个词翻过来读下”注入依赖“&#xff0c;所谓的依赖可以理解成一…...

AI智能名片小程序在促销性内容营销中的创新应用与策略分析

摘要&#xff1a;在数字化时代&#xff0c;企业营销手段日益丰富多元&#xff0c;促销性内容作为吸引顾客、促进消费的关键手段之一&#xff0c;其形式与效率不断被革新。随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;AI智能名片小程序作为一种新兴的营销…...

13. 罗马数字转整数【 力扣(LeetCode) 】

一、题目描述 罗马数字包含以下七种字符: I&#xff0c; V&#xff0c; X&#xff0c; L&#xff0c;C&#xff0c;D 和 M。 字符数值字符数值I1V5X10L50C100D500M1000 例如&#xff0c; 罗马数字 2 写做 II &#xff0c;即为两个并列的 1 。12 写做 XII &#xff0c;即为 X…...