有向图强连通分量Tarjan

Java实现有向图强连通分量的Tarjan算法 1 问题描述 引用自百度百科: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树。搜索时,把当前搜索树中未处理的节点加入一个... 阅读详情

  这几天填鸭赛让人很无语啊。。搞一些听都没听过是什么算法的题。。

  所谓强连通,就是一个图中任意两点都是连通的,比如两个点a,b,既要有a到b的路径,又要有b到a的路径。Tarjan算法是用来算强连通分量的。

  Tarjan算法有两个关键的数组,一个是DFN,记录结点的搜索时间编号,也就是第几个搜索到这个点的。还有一个是LOW,记录这个点能够搜索到的时间编号最小的栈中结点。每次搜索一个点时把这个点加到栈中。当一个点的LOW和DFN相等时,以这个点为根的子树属于一个强连通分量(因为如果不相等,两个点都在栈中,显然可以通过LOW的点可以搜索到DFN这个点,又可以从DFN这个点回溯到LOW的点,这个点必然不是根)。然后就把这个强连通分量都退栈。

Low(u)=Min
{
    DFN(u),
    Low(v),(u,v)为树枝边,u为v的父节点
    DFN(v),(u,v)为指向栈中节点的后向边(非横叉边)
}
void Tarjan(int u)
{
    int p,v;
    DFN[u]=LOW[u]=++time;
    instack[u]=true;
    stack[++top]=u;
    for(p=head[u]; p!=-1; p=e[p].next)
    {
        v=e[p].v;
        if(!DFN[v])
        {
            Tarjan(v);
            if(LOW[v]<LOW[u])
                LOW[u]=LOW[v];
        }
        else if(instack[v]&&DFN[v]<LOW[u])
            LOW[u]=DFN[v];
    }
    if(DFN[u]==LOW[u])
    {
        cnt++;
        do
        {
            v=stack[top--];
            instack[v]=false;
            Belong[v]=cnt;
        }
        while(v!=u);
    }
}
  Belong数组是记录当前结点属于哪一个强连通分量,到最后cnt就是强连通分量的个数。

  填鸭赛是这么个题

B - Popular Cows
Time Limit:2000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u

Description

Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

Input

* Line 1: Two space-separated integers, N and M

* Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

Output

* Line 1: A single integer that is the number of cows who are considered popular by every other cow.

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

  这道题还要缩点,把一个强连通分量缩成一个点,最后如果只有一个点没有出度,那么这个强连通分量包含元素的个数就是答案。判断一个点有没有出度,是看那个点里的元素连接的元素在不在一个Belong里,如果不在,就有出度。若只有一个点没有出度,记下这个点的Belong,再去找有多少个点的Belong等于它。

  写这个的时候看网上有些用的动态分配地址的链表,有些用的什么vector。。不会=。= 不知道为什么一看到链表就觉得不会写,不过好在慢慢写一下还是写出了数组的链表。。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<set>
#define INF 0x3f3f3f3f
#define MAXSTATE 2000007
using namespace std;
struct edge
{
    int v,next;
} e[50010];
int cnt,top,time,head[10010],LOW[10010],DFN[10010],stack[10010],Belong[10010],de[10010];
bool instack[10010];
void Tarjan(int u)
{
    int p,v;
    DFN[u]=LOW[u]=++time;
    instack[u]=true;
    stack[++top]=u;
    for(p=head[u]; p!=-1; p=e[p].next)
    {
        v=e[p].v;
        if(!DFN[v])
        {
            Tarjan(v);
            if(LOW[v]<LOW[u])
                LOW[u]=LOW[v];
        }
        else if(instack[v]&&DFN[v]<LOW[u])
            LOW[u]=DFN[v];
    }
    if(DFN[u]==LOW[u])
    {
        cnt++;
        do
        {
            v=stack[top--];
            instack[v]=false;
            Belong[v]=cnt;
        }
        while(v!=u);
    }
}
int N,M;
int main()
{
    freopen("in.txt","r",stdin);
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        int i,u,v,p,tot=0;
        memset(head,-1,sizeof(head));
        memset(DFN,0,sizeof(DFN));
        memset(de,0,sizeof(de));
        memset(instack,false,sizeof(instack));
        while(M--)
        {
            scanf("%d%d",&u,&v);
            e[tot].v=v;
            e[tot].next=head[u];
            head[u]=tot++;
        }
        top=cnt=time=0;
        for(i=1; i<=N; i++)
        {
            if(!DFN[i]) Tarjan(i);
        }
        //下面是有出度的缩点都标记
        for(i=1; i<=N; i++)
            for(p=head[i]; p!=-1; p=e[p].next)
            {
                if(Belong[i]!=Belong[e[p].v])
                {
                    de[Belong[i]]=1;
                    break;
                }
            }
        int c=0,s,ans=0;
        for(i=1; i<=cnt; i++)
            if(!de[i])
            {
                c++;
                s=i;  //s是没有出度的缩点的编号
            }
        if(c>1) printf("0\n");
        //只有一个缩点没有出度的,答案就是这个点所包含的元素个数
        else
        {
            for(i=1; i<=N; i++)
                if(Belong[i]==s) ans++;
            printf("%d\n",ans);
        }
    }
    return 0;
}


SOLIDWORKS2024安装卡顿?Edge WebView2 Runtime冲突的排查与修复 本文针对SOLIDWORKS 2024安装时setup.exe无响应或卡死的常见问题,深入剖析了其根本原因在于Microsoft Edge WebView2 Runtime的版本冲突或组件损坏。文章提供了三种经过验证的解决方案:一是通过运行安装包内swwi\data目录下的setup.exe直接绕过图形界面;二是彻底卸载并重装官方Edge WebView2 Runtime组件;三是进行系统级修复与排查。旨在帮助用户快速定位并解决安装障碍,顺利完成软件部署。 阅读详情

相关推荐

告别JTAG!用Artix-7和SPI Flash实现FPGA远程升级的保姆级教程

本文详细介绍了如何利用Artix-7 FPGA和SPI Flash实现FPGA远程升级(OTA)的完整方案。通过硬件连接、Vivado工程配置和STM32模拟更新等步骤,帮助开发者告别传统的JTAG烧录方式,实现高效、安全的远程固件更新,特别适用于嵌入式系统开发中的现场维护场景。

weixin_33964987的博客 364

给有向图加边

题意:给一个n×n矩阵,mp[i][j]=1代表i到j之间有一条i指向j的有向边,同一个强联通分量之间可以随便加边,不同强连通分量之间只能有单向连边,问在现有的图的基础上,最多能加多少条边。 题解:tarjan缩点时记录每个连通分量包含的点的数量。ans一开始等于-tot,因为一定会减去现有的边。然后从第一个连通分量开始遍历,用pre记录连通分量点数量的前缀和,每一次,ans+=(num[i]-1...

weixin_43678350的博客 661

hMailServer安装配置

hMailServer安装配置 使用宝塔面板上的宝塔邮件服务器2.1版本,进行安装hMailServer。 宝塔在安装hMailServer是有做了一些配置,如果是手工安装需要注意一下配置点: 1、\hMailServer\Bin 目录下增加mysql连接文件libmysql.dll,要去下载32位的。 libmysql.dll下载 链接:https://pan.baidu.com/s/1YGJXzjowlJ9n_MiqB4xiqw 提取码:wz90 2、 需要提前安装mysql,并创建hM.

王者的博客 5865

有向图的强连通分量 模板

const int MAXN = 10010; //点数 const int MAXM = 100100; //边数 struct edge { int to,next; } edge[MAXM]; int head[MAXN],tot; int Low[MAXN],DFN[MAXN],Stack[MAXN]; int Belong[MAXN]; //标记当前点属于第几个强连通分量

潮鸣り 472

Windows游戏多开检测实战:5种技术原理与破解方法详解(附C++代码)

本文深入解析了Windows游戏多开检测的5种核心技术原理,包括进程枚举、互斥体、信号量、窗口及文件映射检测,并详细探讨了对应的破解方法。通过分析这些基于进程和内核对象的攻防机制,为开发者与逆向爱好者提供了从底层理解Windows系统进程管理的实战视角,并附有核心C++代码示例。

weixin_29315091的博客 243

高效低功耗设计:PMOS电子开关在墨水屏与ADC采样电路中的创新应用

本文深入探讨了PMOS电子开关在低功耗设计中的创新应用,特别是在墨水屏和ADC采样电路中的关键作用。通过详细分析PMOS的导通机制和近乎零静态功耗特性,展示了其在待机低功耗场景下的显著优势,并提供了实用的电路设计技巧和元器件选型建议,帮助工程师实现极致的功耗优化。

weixin_29193359的博客 161

B - Proving Equivalences HDU - 2767 (强连通分量+缩点+加边形成强连通图)

题意:给出n个定理,m个推导关系(单向),求至少加多少个推导关系,可以使得任意两个定理之间可以相互推导出来 思路: 任意两个定理之间可以相互推导,即要构造一个强连通图,使得任意两点之间可以相互到达 求强连通分量,缩点(同一个分量之中的定理可以两两推导出来了) 接下来求加多少条边,可以使得这个DAG图变成强连通图。统计每个分量的出度和入度,若出度为0的点有x个,入度为0的点有y个,则至少要加...

scau_cdx的博客 265

40、5G NR射频要求解析

本文详细解析了5G NR射频相关要求,包括参考灵敏度与动态范围的定义、接收机对干扰信号的抗扰性要求(如阻塞、邻道选择性等)、辐射射频要求在FR1和FR2频段的差异,以及多标准无线电基站(MSR)的发展及其对射频要求的影响。内容涵盖测试模型、干扰场景、具体指标和实现挑战,为理解和应用5G NR射频规范提供了全面指导。

qsc901234的博客 245

有向图强连通分量 Tarjan算法【java实现】

注:本文章上部分内容转载自http://www.cppblog.com/sosi/archive/2010/09/26/127797.html;一方面是网上有很多关于tarjan算法的介绍,我觉得都没有这个他的文章介绍的简明易懂或者没有具体的实现。另一方面,自己也顺便用java实现了一下,所以发表出来和大家分享分享! [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,

u013376508的博客 5453

2026年高教社杯数学建模国赛A题解题思路:从物理方程推导到MATLAB高效求解的全流程实战指南

□所有代码能够从头运行到尾,不报错(清除workspace重新跑一遍)□论文中的每个图号、表号、公式编号与正文引用一致□附录中附上核心代码(注意:不是全部代码,而是关键求解器和后处理部分)□支撑材料压缩包包含完整代码、数据文件、README说明□摘要字数严格控制在1000字以内,突出创新点和核心结果□。

YOLO 109

uniapp - 微信小程序接入官方人脸识别认证详细流程及示例源码,Uniapp微信小程序项目集成官方提供的人脸识别身份验证插件接口(多种示例:人脸核验、身份证件与人脸是否匹配、是否活体、实名认证等)

uni-app微信小程序人脸识别认证,使用uniapp开发微信小程序的人脸采集功能/人脸识别功能,uniapp vue3微信小程序活体人脸识别,Uni-app微信小程序实名认证,uniApp微信小程序人脸认证,UniApp的微信小程序实名认证与人脸识别系统开发,人脸核身微信小程序uni-app接入流程,wx.startFacialRecognitionVerify,uniapp开发微信小程序-人脸采集功能、微信人脸识别实名认证集成指南,识别失败,人脸识别接口怎么调用,前后端完整示例代码demo,人脸检测功能

🏆 前端领域优质创作者 3277

Tarjan算法 求解有向图强连通分量

一.算法简介 Tarjan 算法一种由Robert Tarjan提出的求解有向图强连通分量的算法,它能做到线性时间的复杂度。 我们定义: 如果两个顶点可以相互通达,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components)。 例如:在上图中,...

flymoyu的博客 419

(十二)深入理解蓝牙BLE之“移植Bluez 5.18源码到嵌入式平台”

在某嵌入式平台进行蓝牙开发,发现上面居然没有btmon,hciattach,hcitool等蓝牙调试工具,无奈之下,只好移植bluez协议栈到目标嵌入式平台,建议移植5.18版本(最新的5.54版本居然hcitool等工具不是默认编译的,需要修改Makefile才可以)。 看到很多讲解移植过程的文章都是需要积分的,觉得写一篇免积分的文章还是有些意义的,欢迎同行来交流。 移植环境:Linux ubuntu 目标平台:sigmastar 星宸科技 配置交叉编译工具链:export PATH=$PATH:

2964

有向图强连通分量Tarjan算法

在https://www.byvoid.com/zhs/blog/scc-tarjan中关于Tarjan算法的描述非常好,转述如下: 首先解释几个概念: 有向图强连通分量:在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。 如果有向图G的每两个顶点都强连通,则称G是一个强连通图。 非强连通图有向图的极大强连通子图,成为强连通分...

aling1199的博客 462

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Tarjan 算法求有向图强连通分量+tarjan模板

Tarjan 算法求有向图强连通分量+tarjan模板 强连通分量定义 有向图强连通分量:在有向图G中,如果两个顶点**v<sub>i</sub>**,**v<sub>j</sub>**间(**v<sub>i</sub>**>**v<sub>j</sub>**)有一条从**v<sub&gt...

王蒟蒻 327

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

[转载] 有向图强连通分量的Tarjan算法 ——byvoid

[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达。{5},{6}也分别是两

Miracles happen every day. 1399

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

有向图强连通分量的Tarjan算法

转自BYVoid [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1...

diuliaoquan1673的博客 76

有向图强连通分量之Tarjan算法

出处https://www.byvoid.com/zhs/blog/scc-tarjan [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected components)。 下图中,子...

Akatsuki 545

有向图强连通分量(Tarjan)算法

在图论中,连通图基于连通的概念。在一个无向图G 中,若从顶点到顶点有路径相连(当然从到也一定有路径),则称和是连通的。如果 G 是有向图,那么连接和的路径中所有的边都必须同向。如果图中任意两点都是连通的,那么图被称作连通图。强连通图指每一个顶点皆可以经由该图上的边抵达其他的每一个点的有向图。意即对于此图上每一个点对(Va,Vb),皆存在路径Va→Vb以及Vb→Va。强连通分量则是指一张有向图

lqcsp的专栏 1052

有向图强连通分量tarjan算法

转自:http://www.byvoid.com/blog/scc-tarjan/ http://blog.youkuaiyun.com/geniusluzh/article/details/6601514 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通图有向图的极大强连通子

chivalry 722
上一篇: hash
下一篇: poj3254 poj1185 状态压缩DP
小小小小葱
博客等级 码龄14年 22粉丝 266原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值