缩点常应用于给一个有向图,求在图中最少要加多少条边能使得该图变成一个强连通图

首先求出该图的各个强连通分量,然后把每个强连通分量看出一个点(即缩点),最后得到了一个有向无环图(DAG)

对于一个DAG,需要添加 max(a,b) 条边才能使其强连通

其中 a 为 DAG 中出度为 0 的点总数,b 为 DAG 中入度为 0 的点总数

int n,m;
vector<int> G[N];
stack<int> S;
int dfn[N],low[N];
bool vis[N];//标记数组
int sccno[N];//记录结点i属于哪个强连通分量
bool in[N],out[N];//记录入度、出度是否为0
int block_cnt;//时间戳
int sig;//记录强连通分量个数
void Tarjan(int x){vis[x]=true;dfn[x]=low[x]=++block_cnt;//每找到一个新点,纪录当前节点的时间戳S.push(x);//当前结点入栈for(int i=0;i<G[x].size();i++){//遍历整个栈int y=G[x][i];//当前结点的下一结点if(vis[y]==false){//若未被访问过Tarjan(y);low[x]=min(low[x],low[y]);}else if(!sccno[y])//若已被访问过,且不属于任何一个连通分量low[x]=min(low[x],dfn[y]);}if(dfn[x]==low[x]){//满足强连通分量要求sig++;//记录强连通分量个数while(true){//记录元素属于第几个强连通分量int temp=S.top();S.pop();sccno[temp]=sig;if(temp==x)break;}}
}
void shrink(){//缩点memset(in,false,sizeof(in));memset(out,false,sizeof(out));for(int i=1;i<=sig;i++){//对于所有的强连通分量,将其入度、出度均视为1in[i]=true;out[i]=true;}for(int x=0;x<n;x++){//枚举n个点for(int i=0;i<G[x].size();i++){//对第x个点的每个后继节点int y=G[x][i];if(sccno[x]!=sccno[y]){//统计每个点出度、入度是否为0out[sccno[x]]=false;in[sccno[y]]=false;}}}
}
int main()
{int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);for(int i=0;i<n;i++)G[i].clear();while(m--){int x,y;scanf("%d%d",&x,&y);x--;y--;G[x].push_back(y);}sig=0;block_cnt=0;memset(vis,false,sizeof(vis));memset(dfn,0,sizeof(dfn));memset(low,0,sizeof(low));memset(sccno,0,sizeof(sccno));//Tarjan求强连通分量for(int i=0;i<n;i++)if(vis[i]==false)Tarjan(i);shrink();//缩点int a=0,b=0;for(int i=1;i<=sig;i++){//统计入度、出度为0的点的个数if(in[i])a++;if(out[i])b++;}int res=max(a,b);if(sig==1)//强连通分量为1时res=0;printf("%d\n",res);}
}

图论 —— 图的连通性 —— Tarjan 缩点相关推荐

  1. 图论 —— 图的连通性 —— Tarjan 求双连通分量

    [概念] 1.双连通分量:对于一个无向图,其边/点连通度大于1,满足任意两点之间,能通过两条或两条以上没有任何重复边的路到达的图,即删掉任意边/点后,图仍是连通的 2.分类: 1)点双连通图:点连通度 ...

  2. 图论 —— 图的连通性 —— Tarjan 求割点与桥

    [概念] 1.割点 1)割点:删除某点后,整个图变为不连通的两个部分的点 2)割点集合:在一个无向图中删除该集合中的所有点,能使原图变成互不相连的连通块的点的集合 3)点连通度:最小割点集合点数 如上 ...

  3. 图论 —— 图的连通性 —— Tarjan 求强连通分量

    [概述] Tarjan 算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树. 搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量. [ ...

  4. 图论 —— 图的连通性

    [基本概念] 1.连通图与连通分量 1)连通图:无向图 G 中,若对任意两点,从顶点 Vi 到顶点 Vj 有路径,则称 Vi 和 Vj 是连通的,图 G 是一连通图 2)连通分量:无向图 G 的连通子 ...

  5. 图论 —— 图的连通性 —— 传递闭包

    [概述] 传递闭包:对于一个节点 i,如果 j 能到 i,i 能到 k,那么 j 就能到 k,求传递闭包,就是把图中所有满足这样传递性的节点计算出来,计算完成后,就知道任意两个节点之间是否相连. 简单 ...

  6. 图论 —— 图的连通性 —— 有桥连通图加边变边双连通图

    对于一个有桥的连通图,加边变成边双连通图 1.求出所有的桥,然后删除这些桥边.剩下的每个连通块都是一个双连通子图. 2.把每个双连通子图收缩为一个顶点. 3.加回桥边,统计度为1的节点的个数(叶节点的 ...

  7. 图论 —— 图的连通性 —— Kosaraju 算法

    [概述] Kosaraju 算法是最容易理解,最通用的求强连通分量的算法,其关键的部分是同时应用了原图 G 和反图 GT . [基本思想] 1.对原图 G 进行 DFS 搜索,计算出各顶点完成搜索的时 ...

  8. 图论 —— 图的连通性 —— 并查集判断连通性

    当需要判断图是否为连通图时,可以使用并查集来进行连通分量的统计,若连通分量大于 1,则说明图中存在多个连通分量,图不为连通图. int n,m; int father[N]; int Find(int ...

  9. 图论复习之强连通分量以及缩点—Tarjan算法

    图论复习之强连通分量以及缩点-Tarjan算法                                 by RtPYH ----------------------------------- ...

最新文章

  1. linux条件表达式例子,Linux的Iptables命令的基本知识(三)-常用匹配条件示例和执行动作...
  2. wxWidgets:线程间和进程间通信
  3. SAP Spartacus 里的 .release-it.json 文件
  4. SAP C4C产品主数据OData服务的ETag处理
  5. centos永久关闭防火墙
  6. TIOBE 2021年3月程序语言排名 - python要超越Java排第二了?
  7. MySql 5.6.36 64位绿色版安装
  8. 软件测试面试:请说一下你工作中发现的最有价值的bug?
  9. 第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛题解
  10. 手机点餐系统概述_自助点餐、自助收银......在餐饮行业有哪些智慧化场景?
  11. XP框架管理器EdXposed v4.6.2 (46200)
  12. 智慧酒店系统开发给现代酒店运营注入创新活力
  13. mrpt在win8.1 64bit + vs2013环境下的安装和编译
  14. couchbase php,轻松搞定|将PHP和Couchbase应用部署为Docker
  15. matlab怎么表示分块矩阵,急求一个测量矩阵采用分块多项式矩阵时怎样引用的代码!!!...
  16. 51单片机入门——LED灯
  17. 人工智能调度如何改变现场服务行业
  18. [VOT10](2022CVPR)TCTrack: Temporal Contexts for Aerial Tracking
  19. JDBC操作数据库——resultset的操作小窍门
  20. 全息投影马戏团,好有爱的科技呀~

热门文章

  1. 普林斯顿校长2018演讲:读书无用是最大的谎言
  2. STM32之DAC原理
  3. ST-Link刷成J-Link
  4. STM32之SPI原理
  5. python元组和列表字典_python:列表、元组和字典
  6. 数据源管理 | 主从库动态路由,AOP模式读写分离
  7. /etc/fstab文件分析(第二版)
  8. Linux 学习笔记_12_文件共享服务_4_SSH
  9. 《运营之光》《策略产品经理》《推荐系统实践》读书笔记随笔
  10. 手机定位App从想法到上线运营(1)--介绍