昨天一看发现我的博客数量到100篇了,撒花✿✿ヽ(°▽°)ノ✿


根据标题我们也知道,想要在接下来的十分钟不浪费生命

读者需要先行学习Tarjan强联通分量

如果不会的话可以点击这里:https://www.cnblogs.com/WWHHTT/p/9744658.html

好的,现在我们就假设大家都知道了Tarjan,来看看如何利用Tarjan缩点

在学习如何写代码之前,我们必须要先弄明白什么是缩点

也就是定义

百度百科上并没有给出详细解释,我就来总结几句

缩点就是把一个有向图中的强联通分量转换成一个点

转换完之后的图是一个DAG(有向无环图)

通常用来解决图中具有传递性的问题(还有最大值和乘法原理)

我们来举个例子吧

上面这个图中,圆里的是编号,红色的是点的权值,箭头代表边的方向

这个图缩点之后是这样的

符号所表示的东西不变,原来的2,3,4变成了现在的2,原来的5是现在的3

是不是感觉没有多难,下面我来带大家看一下具体的实现流程

分为两步:

1.求出图中的强联同分量,并转化为点

2.将转化出来的新的点建成一个新的图

step1:

如何求出强联通分量就不多说了(不会的去看上面的链接)

每一种强联通分量会缩成一个点,这个店的编号我们就定为发现它的顺序,也就是染上的颜色

每一种颜色(一个强联通分量)对应一个点

但是要在中间加一个操作,用来计算一个联通分量的所缩成的点的点权(看注释)

void Tarjan(int x,int fa){//Tarjan模板 low[x]=dfn[x]=++tot;sta[++size]=x;book[x]=1;for(int e=head1[x];e;e=nxt1[e]){if(!dfn[to1[e]]){Tarjan(to1[e],x);low[x]=min(low[x],low[to1[e]]);}else if(book[to1[e]]) low[x]=min(low[x],dfn[to1[e]]);}if(dfn[x]==low[x]){color[x]=++color_cnt;v2[color_cnt]=v[x];book[x]=0;while(sta[size]!=x){color[sta[size]]=color_cnt;book[sta[size]]=0;v2[color_cnt]+=v[sta[size]];//这个点的权值的计算,根据题目来确定 size--;}size--;}return ;
}

step2:
建图的边怎么练一直是个难点,首先可以确定的是因为原来的强连通分量已经变成一个个的点了

所以肯定无法照搬原图

但也不可能自创,所以需要判断,从原来的图上选择那些边

选边的原则是不能是一个强连通分量里的边

也就是说别的边都可以选

那么有的人就问了,缩完点之后不担心友谊重边吗

这很好处理,用邻接矩阵来存(不推荐),或者在之后的程序中标记都可以

特别提到,印的图要用一个新的邻接表来存

而且要连接的不是原来的点,而是两个点被染成的颜色

代码实现的话很简单,循环和dfs都可以,这里我们采用循环(代码量较小)

void change(){for(int i=1;i<=n;i++){for(int e=head1[i];e;e=nxt1[e]){if(color[i]!=color[to1[e]]) add2(color[i],color[to1[e]]);}}return ;
}

那么最后我们来总结一下代码

先给一组数据:(对应上面的图)
5 5   //点的数量  边的数量

1 1 1 1 1   //点权

1 2  //边

2 3

3 4

4 2

2 5

输出:

3 //新的点的数量

1 3 1   //新的点的权值

下面给出代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
inline int min(int a,int b){return a<b?a:b;}
inline int max(int a,int b){return a>b?a:b;}
inline int rd(){int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';return x*f;
}
inline void write(int x){if(x<0) putchar('-'),x=-x;if(x>9) write(x/10);putchar(x%10+'0');return ;
}
int n,m;
int v[100006];
int head1[100006],nxt1[200006],to1[200006];
int total1=0;
void add1(int x,int y){total1++;to1[total1]=y;nxt1[total1]=head1[x];head1[x]=total1;return ;
}
int dfn[100006],low[100006];
int color[100006];
int tot=0;
int color_cnt=0;
int book[100006];
int sta[100006];
int v2[100006];
int size=0;
void Tarjan(int x,int fa){//Tarjan模板 low[x]=dfn[x]=++tot;sta[++size]=x;book[x]=1;for(int e=head1[x];e;e=nxt1[e]){if(!dfn[to1[e]]){Tarjan(to1[e],x);low[x]=min(low[x],low[to1[e]]);}else if(book[to1[e]]) low[x]=min(low[x],dfn[to1[e]]);}if(dfn[x]==low[x]){color[x]=++color_cnt;v2[color_cnt]=v[x];book[x]=0;while(sta[size]!=x){color[sta[size]]=color_cnt;book[sta[size]]=0;v2[color_cnt]+=v[sta[size]];//这个点的权值的计算,根据题目来确定 size--;}size--;}return ;
}
int head2[100006],nxt2[200006],to2[200006];
int total2=0;
void add2(int x,int y){total2++;to2[total2]=y;nxt2[total2]=head2[x];head2[x]=total2;return ;
}
void change(){for(int i=1;i<=n;i++){for(int e=head1[i];e;e=nxt1[e]){if(color[i]!=color[to1[e]]){add2(color[i],color[to1[e]]);//将两个点连边
            }}}return ;
}int main(){n=rd(),m=rd();for(int i=1;i<=n;i++) v[i]=rd();//得到点权 for(int i=1;i<=m;i++){int x=rd(),y=rd();add1(x,y);//有向边
    }for(int i=1;i<=n;i++) if(!dfn[i]) Tarjan(i,0);change();int ans=0;printf("%d\n",color_cnt);for(int i=1;i<=color_cnt;i++){printf("%d ",v2[i]);}return 0;
}

转载于:https://www.cnblogs.com/WWHHTT/p/9825766.html

浅谈Tarjan缩点(分析+模板)相关推荐

  1. 浅谈 CRTP:奇异递归模板模式

    浅谈 CRTP:奇异递归模板模式 前言 建议先看一遍文末的参考资料! 建议先看一遍文末的参考资料! 建议先看一遍文末的参考资料! 思维导图 一.CRTP 是什么 CRTP 全称 : Curiously ...

  2. 浅谈:Spring Boot原理分析,切换内置web服务器,SpringBoot监听项目(使用springboot-admin),将springboot的项目打成war包

    浅谈:Spring Boot原理分析(更多细节解释在代码注释中) 通过@EnableAutoConfiguration注解加载Springboot内置的自动初始化类(加载什么类是配置在spring.f ...

  3. Android 系统(104)---浅谈ANR及log分析ANR

    浅谈ANR及log分析ANR 一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1:KeyDispatchTime ...

  4. 物联网安全专题 | 浅谈物联网设备安全分析方法 — 软件篇

    ✦前 言✦ • 物联网(Internet of Things,IoT)是互联网的延伸,是智能设备.移动网络及社交网络的结合体,可以给使用者提供更优质的应用体验.物联网时代的到来引入了大量的物联网设备, ...

  5. 化学数据分析计算机,浅谈数据处理在化学分析中的应用

    摘要:介绍了数据处理在化学分析中的内容,集中阐述了数据处理在化学分析中的应用方面和具体内容,并且对数据处理在化学分析中的处理和分析进行了详细的探究,给数据处理在化学分析中的应用带来了先进的指导意义. ...

  6. 浅谈动感歌词-歌词分析篇

    1引言 关于动感歌词,我们都不陌生,最常见的就是去唱K时,MV上面的歌词,还有就是酷狗.天天动听和QQ音乐等播放器的歌词,它们都是属于动态歌词,它们都是精确到每个[字],这大大提高了用户的体验.如果一 ...

  7. 浅谈ANR及log分析ANR

    一:什么是ANR ANR:Application Not Responding,即应用无响应 二:ANR的类型 ANR一般有三种类型: 1:KeyDispatchTimeout(5 seconds) ...

  8. MyBatis系列之浅谈SQL执行流程分析

    目录 独立使用Mybatis Mybatis执行流程 SqlSessionFactory\SqlSession MapperProxy Excutor 独立使用Mybatis 这篇文章主要以分析Myb ...

  9. 浅谈 NLP 细粒度情感分析(ABSA)

    作者 | 周俊贤 整理 | NewBeeNLP 最近在调研细粒度情感分析的论文,主要对一些深度学习方法进行调研,看论文的同时记录下自己的一些想法. 首先,何为细粒度的情感分析?如下图,淘宝APP上某商 ...

最新文章

  1. B - Dungeon Master POJ - 2251
  2. 中国云计算厂商营收排名:阿里云完虐微软
  3. 基于小波shint/DCT编码压缩解压缩的FPGA实现
  4. 2020 年腾讯新增 20 亿行代码,鹅厂第一编程语言还是它
  5. GO恶意样本实例分析
  6. ES6公用跑马灯抽奖组件的封装及使用
  7. MySql 存储大量长字节 Text报错处理办法
  8. 51Nod-1014 X^2 Mod P【暴力】
  9. python开发app1001无标题_Python代写:CSSE1001 Dots Co帮做Python编程作业
  10. Servlet和JSP
  11. 乒乓球单循环赛_乒乓球单循环比赛规则
  12. 计算机关于职业与道德的论文怎么写,计算机职业道德论文提纲模板 计算机职业道德论文大纲怎么写...
  13. 织梦的网站地图怎么做html,织梦自带网站地图的生成制作方法详解
  14. ps css圆形路径文字,ps圆形路径文字怎么做
  15. Python利用 Django开发网站
  16. 什么是数据库防火墙 数据库防火墙作用是什么
  17. uchome开发入门
  18. React Native系列——WebView组件使用介绍
  19. 什么是域名 和 域名服务器(DNS)???
  20. “大众点评开发者平台”正式上线

热门文章

  1. 边缘设备上的实时AI人员检测:以实时模式检测视频中的人员
  2. win10 python免安装_使用Python编写免安装运行时、以Windows后台服务形式运行的WEB服务器...
  3. php中英文版切换最好的办法,php做项目进行中英文的切换,如何快速实现
  4. linux安装配置java,Linux 安装配置 java 环境
  5. 使用echarts(二)自定义图表折线图
  6. ctc与临时限速服务器信息,基于CTC站场图图形元素设置高速铁路临时限速的方法...
  7. java 面向对象多态_乐字节Java面向对象三大特性以及Java多态
  8. signature=12e3283d637b587235bcb4cbbfa1a5b3,A pathogen-inducible endogenous siRNA in plant immunity
  9. idea控制台中文乱码问题
  10. 计算机视觉技术测试物体距离,应用计算机视觉技术检测物体的形变