第1节 连通性强连通、割点和桥(一)

文章目录

  • 无向图割点、桥、双连通分量
    • Tarjan算法求割点和桥(割边)
    • 代码:
    • 边双连通分量 和 点双连通分量
    • 代码
    • 边双连通分量 和 点双连通分量 的缩点
  • 有向图的弱连通与强连通
    • 强连通分量
    • Kosaraju算法
    • Tarjan算法
    • 代码:

无向图割点、桥、双连通分量

• 给定无向联通图G=(V,E) • 对于一个点x,若从图中删除x及所有与x相连的边,图不再联通,x是G的割点
• 对于一条边e,从图中删去e,图不再联通,e的x的割边
• 一个图如果不存在割点,则它是一个点双连通图,一个图的极大点双连通子图是他的点双连
通分量。
• 一个图如果不存在割边,则它是一个边双连通图,一个图的极大边双连通子图是他的边双连
通分量。

Tarjan算法求割点和桥(割边)

时间戳dfn :第n个搜到这个点
返祖边:搜索树上一个点连向其祖先节点的边
横插边:搜索树上一个点连向它另一条支链上的点的边----在无向图中不存在
追溯值low:当前点及其子树的返祖边能连到的dfn值最小的点
如果<u,v>是搜索树的边:low[u]=min(low[u],low[v])
在这里插入图片描述
在这里插入图片描述
• u点是割点,v是u搜索树上的一个儿子:dfn[u] <= low[v] ——v的子树中没有返祖边能跨越u点;有多个儿子的根节点
比如图中的点10和点7

• 边是桥,搜索树上v是u的儿子:dfn[u]<low[v]——v的子树中没有返祖边能跨越<u,v>这条边

代码:

void tarjan(int x)//求割点 
{dfn[x]=low[x]=++cnt;int flag=0;for(int i=head[x];i;i=edge[i].next){int v=edge[i].v;if(!dfn[v]){tarjan(v);low[x]=min(low[x],low[v]);if(low[v]>=dfn[x]){flag++;if(x!=root||flag>1)book[x]=1;//flag>!说明根有两个以上的儿子 }}else low[x]=min(low[x],dfn[v]);} 
}

求割边:if(low[v] > dfn[x])

边双连通分量 和 点双连通分量

• 把桥删了每个连通块都是一个边双联通分量——标记出桥之后dfs一遍即可
• 点双连通分量要复杂一些——一个割点可能属于多个双联通分量

点双连通分量性质:
任意两点间至少存在两条点不重复的路径等价于图中删去任意一个点都不会改变图的连通性,即BCC中无割点
若BCC间有公共点,则公共点为原图的割点
无向连通图中割点一定属于至少两个BCC,非割点只属于一个BC

点双连通分量求法::
• 维护一个栈
• 第一次访问某个节点时,将其入栈
• 当割点判断法则中dfn[x]<=low[y]成立时,不断从栈中弹出节点,直到y被弹出,这些被弹出的点和x一起构成一个点双连通分量

代码

#include<cstdio>
#include<cctype>
#include<vector>
using namespace std;
struct edge
{int to,pre;
}edges[1000001];
int head[1000001],dfn[1000001],dfs_clock,tot;
int num;//BCC数量 
int stack[1000001],top;//栈 
vector<int>bcc[1000001];
int tarjan(int u,int fa)
{int lowu=dfn[u]=++dfs_clock;for(int i=head[u];i;i=edges[i].pre)if(!dfn[edges[i].to]){stack[++top]=edges[i].to;//搜索到的点入栈 int lowv=tarjan(edges[i].to,u);lowu=min(lowu,lowv);if(lowv>=dfn[u])//是割点或根 {num++;while(stack[top]!=edges[i].to)//将点出栈直到目标点 bcc[num].push_back(stack[top--]);bcc[num].push_back(stack[top--]);//目标点出栈 bcc[num].push_back(u);//不要忘了将当前点存入bcc }}else if(edges[i].to!=fa)lowu=min(lowu,dfn[edges[i].to]);return lowu;
}
void add(int x,int y)//邻接表存边 
{edges[++tot].to=y;edges[tot].pre=head[x];head[x]=tot;
}
int main()
{int n,m;scanf("%d%d",&n,&m);for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);add(x,y),add(y,x);}for(int i=1;i<=n;i++)//遍历n个点tarjan if(!dfn[i]){stack[top=1]=i;tarjan(i,i);}for(int i=1;i<=num;i++){printf("BCC#%d: ",i);for(int j=0;j<bcc[i].size();j++)printf("%d ",bcc[i][j]);printf("\n");}return 0;
}

边双连通分量 和 点双连通分量 的缩点

• 每个边双连通分量缩成一个点,再用原来的桥把他们连起来
• 点双联通分量因为一个割点可能包含在多个点双连通分量里面,所以我们将每个割点保留割点与其所在的点双连通分量连边即可。

有向图的弱连通与强连通

• 在有向图G=(V,E)中,如果对于任意两点u,v,存在一条从u到v或者从v到u的路径——弱联通
• 在有向图G=(V,E)中,如果对于任意两点u,v都互相可达——强联通

强连通分量

• 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路
径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。 • 如果有向图G的每两个顶点都强连通,称G是一个强连通图。
• 有向图的极大强连通子图,称为强连通分量(strongly connected components)。
在这里插入图片描述

Kosaraju算法

• 对原图进行一次dfs(任意起点)
• 在第一次形成的森林的每一颗树里,以第一次搜索出栈时间的逆序对反图进行dfs,这次搜索A能到达的点和A都在一个强连通分量里面
在这里插入图片描述

Tarjan算法

• Dfn[n]时间戳
• Low[n]他和他的子树里返祖边和横叉边能连到还没出栈的dfn最小的点
• 在dfs的时候维护一个栈第一次访问到某个点就将其加入到栈中,当一个点x的dfn[x] == low[x] 时,他就是这个强连通分量里面在搜索树中最高的点,将栈里点出栈直到x也出栈为止,这些点组成一个强连通分量。

代码:

void tarjan(int x)
{dfn[x]=low[x]=++cnt;stack[++top]=x;vis[x]=1;//x是否在栈里 for(int i=head[x];i;i=edge[i].next){int v=edge[i].v;if(!dfn[v]){tarjan(v);low[x]=min(low[x],low[y]);}else if(vis[v])low[x]=min(low[x],dfn[v]);if(dfn[x]==low[x])//是否是强连通分量最高的点 {ans++;//新强连通的标号 do{int cur=stack[top--];//栈顶的点 vis[cur]=false;num[cur]=ans;}while(x!=cur);}}} 

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

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

相关文章

连通性(相关练习)

文章目录NC20603 [ZJOI2007]最大半连通子图题目&#xff1a;题解&#xff1a;代码&#xff1a;NC50403 嗅探器题目&#xff1a;题解&#xff1a;代码&#xff1a;NC51269 Network of Schools题目&#xff1a;题解&#xff1a;代码&#xff1a;NC106972 Cow Ski Area题目&#x…

ASP.NET Core WebAPI中使用JWT Bearer认证和授权

为什么是 JWT BearerASP.NET Core 在 Microsoft.AspNetCore.Authentication 下实现了一系列认证, 包含 Cookie, JwtBearer, OAuth, OpenIdConnect 等,Cookie 认证是一种比较常用本地认证方式, 它由浏览器自动保存并在发送请求时自动附加到请求头中, 更适用于 MVC 等纯网页系统的…

网络流专题(最大流与费用流)(一)

流量网络 • 想要将一些水从S运到T&#xff0c;必须经过一些水站&#xff0c;链接水站的是管道&#xff0c;每条管道都有它的最大能容纳的水量&#xff0c;求最多S到T能流多少流量。 基本概念 • 这是一个典型的网络流模型。我们先了解网络流的有关定义和概念。 • 若有向图G(…

eShopOnContainers 看微服务 ①:总体概览

一、简介eShopOnContainers是一个简化版的基于.NET Core和Docker等技术开发的面向微服务架构的参考应用。该参考应用是一个简化版的在线商城/电子商务微服务参考示例应用。其包含基于浏览器的Web应用、基于Xamarin的Android、IOS、Windows/UWP 移动应用&#xff0c;以及服务端应…

网络流专题(最大流与费用流)例题总结

文章目录NC 106056 poj1459 Power Network题目大意&#xff1a;题解&#xff1a;NC213817 [网络流24题]最小路径覆盖问题题目&#xff1a;题解&#xff1a;例2&#xff1a;NC213818 [网络流24题]魔术球问题题目&#xff1a;题解&#xff1a;方法2&#xff1a;NC 213820 [网络流…

周期长度和(KMP)

文章目录题目描述解析问题总结代码题目描述 解析 我们可以看到 如果A是B的周期 那么B一定可以写成&#xff1a; A1A2A1 的形式 注意到&#xff1a;A1就是KMP中的公共前后缀 要使A最大&#xff0c;要使A1最短 也就是求最短公共前后缀 这怎么求呢&#xff1f; 我们注意到&#x…

计算几何基础-1

文章目录基本概念点与向量的运算精度问题线段&#xff0c;射线和直线点积&#xff1a;夹角叉积向量的极角旋转一个向量求三角形面积直线交点点到直线距离点在直线上的投影判断两条线段是否相交点与直线的位置关系点是否在直线左侧点是否在直线上点是否在线段上点与多边形的位置…

.net core i上 K8S(四).netcore程序的pod管理,重启策略与健康检查

目录1.pod管理2.重启策略3.健康检查4.进入容器正文上一章我们已经通过yaml文件将.netcore程序跑起来了&#xff0c;但还有一下细节问题可以分享给大家。1.pod管理1.1创建podkubectl create -f netcore-pod.yaml我们创建一个netcore-pod.yaml文件&#xff0c;内容如下&#xff1…

洛谷P2680:运输计划(倍增、二分、树上差分)

传送门 文章目录题目描述解析问题代码题目描述 解析 求最大值的最小值 容易想到二分 然后。。。就没有然后了。。。 看了题解 学会了一个新技能&#xff1a;树上差分 &#xff08;其实学长之前好像讲过。。。&#xff09; 一般的&#xff0c;对于一条A到B的路径&#xff0c;如…

计算几何基础-2

文章目录直线&#xff1a;图形&#xff1a;求垂足求两圆交点直线与圆交点多边形问题判断一个点是否在任意多边形内部Pick定理凸包求点集的凸包水平法&#xff1a;增量法&#xff1a;半平面半平面交求半平面交直线&#xff1a; struct Line{point p,v;Line(){}Line(point _p.po…

eShopOnContainers 看微服务 ②:配置 启动

一、什么是dockerDocker 是一个开源项目&#xff0c;通过把应用程序打包为可移植的、自给自足的容器&#xff08;可以运行在云端或本地&#xff09;的方式&#xff0c;实现应用程序的自动化部署。使用 Docker 的时候&#xff0c;需要创建一个应用或服务&#xff0c;然后把它和它…

判断整除(opj)(动态规划)

解析 与取模结合的动归&#xff0c;正常做即可 问题 眼瞎&#xff01;&#xff01;&#xff01; 这个序列的每个数都必须用到&#xff01;&#xff01;&#xff01; if(f[i-1][j]) f[i][j]1;上面这行就是不对的&#xff01;&#xff01;&#xff01; 头疼 仔细审题 opj的题…

[USACO09FEB]Revamping Trails G

题意&#xff1a; 约翰一共有 N 个牧场.由 MM 条布满尘埃的小径连接。小径可以双向通行。每天早上约翰从牧场 1 出发到牧场 N 去给奶牛检查身体。 通过每条小径都需要消耗一定的时间。约翰打算升级其中 K 条小径&#xff0c;使之成为高速公路。在高速公路上的通行几乎是瞬间完…

NET Core微服务之路:自己动手实现Rpc服务框架,基于DotEasy.Rpc服务框架的介绍和集成...

本篇内容属于非实用性&#xff08;拿来即用&#xff09;介绍&#xff0c;如对框架设计没兴趣的朋友&#xff0c;请略过。 快一个月没有写博文了&#xff0c;最近忙着两件事;一&#xff1a;阅读刘墉先生的《说话的魅力》&#xff0c;以一种微妙的&#xff0c;你我大家都会经常遇…

花店橱窗布置(洛谷P1854)(动态规划)

传送门 文章目录解析问题代码解析 一道很正常的动态规划 dp[i][j]表示到第j个花瓶放了第j朵花的dp最优值 注意&#xff1a;是严格使第i朵放在j瓶 找到最优解递归输出即可 问题 又是初始化的问题&#xff01;&#xff01;&#xff01; 一开始把dp赋值成负无穷时落掉了j0的一行…

P4009 汽车加油行驶问题

题目描述&#xff1a; 题解&#xff1a; 看了很多题解&#xff0c;无论什么解法都绕不开分层图 在本题中加满油的车每次可以移动K步&#xff0c;那么我们就可以建立一个K1层的分层图&#xff0c;表示汽车油量k的状态&#xff08;油量0…k&#xff09;&#xff0c;然后根据题目…

.net core i上 K8S(五).netcore程序的hostip模式

正文上一章讲了pod的管理&#xff0c;今天再分享一个pod的访问方式1.Pod的HostIP模式Pod的HostIP模式&#xff0c;可以通过宿主机访问pod内的服务&#xff0c;创建yaml文件如下apiVersion: v1 kind: Pod metadata: name: netcore-podlabels:app: netcorepod spec:containers: …

状态压缩:枚举子集(最优组队)(ybtoj)(动态规划)

解析 很裸的状压dp 但是直接暴力的话状态2n,枚举2n 乘在一起会T诶 怎么办呢&#xff1f; 使用下面这个循环&#xff0c;就可以保证只会枚举当前状态s的子集 for(int i(s-1)&s;i;i(i-1)&s){........ }证明 举举例子就挺明显了 为什么不重不漏呢&#xff1f; 首先i肯…

【活动(深圳)】告别2018之12.22 大湾区.NET Meet 大会 ,同时有网络直播

今年的 Connect(); 主题更加聚焦开发者工具生产力、开源&#xff0c;以及无服务器&#xff08;Serverless&#xff09;云服务。Visual Studio 2019 AI 智能加持的 IntelliCode、实时代码协作共享 Live Share&#xff0c;.NET Core 3.0的预览版本附带了大量更新&#xff0c;旨在…

最短路径(状压dp)(ybtoj)

解析 “bug总有de完的一天” 头疼 暴力写的话本题显然复杂度是假的 有一个很好的思路优化时间复杂度 先用dp[k][i]表示**从第k个关键点到任意i点的最短路 跑k遍 SPFA或迪杰斯特拉 即可 然后转移时可以只考虑关键点 使状态转移数大大降低 细节 头真疼 边界条件&#xff1a; …