算法学习之路|强连通分量+缩点

简介: 路漫漫其修远兮,算法学习

本来寒假是安排的很充实的,放假了一回到家就(ノへ ̄、)
算法想想还是不能丢,虽然离ACM铜牌的水平还差好远,但是,不想留下遗憾,算法慢慢的要重新拾起来的,虽然以前水平也不咋地╯︿╰

原题为2017icpc亚洲区预赛乌鲁木齐网络赛F题island

https://nanti.jisuanke.com/t/16955

题目大意:一张有向图,问至少再添加几条有向边,才能使它成为强连通图。

主要写一下本题大致用到了哪些方面的知识,理一下思路。

强连通分量:在有向图中,如果一张图中的任意两点都可以相互到达,则称这个图为强连通图。图中任意两点之间可以相互到达的子图即为强连通分量。

tarjan算法:本质是通过一次dfs搜索有向图,用栈存储到达过的节点,每求出一个完整的强连通分量,就弹出对应的节点,计算强连通分量的个数(即之后缩点后点的个数)。

tarjan算法的详解可以看这位博主的博客:

http://blog.csdn.net/jeryjeryjery/article/details/52829142?locationNum=4

缩点:在每次求得一个强连通分量时,给当前强连通分量中的节点打上同一个标记,看成同一个节点,即缩点。

入度、出度:如有向边(u,v)不在同一个强连通分量中,则u所在强连通分量出度++,v所在强连通分量入度++。

计算入度为0和出度为0的强连通分量个数n,m

构成强连通图需要添加的最少边就是max(n,m),因为出度为0的点无法到达其他节点,入度为0的点无法被到达,则至少使得所有点入度和出度都大于0才能构成强连通图。

tarjan算法代码

注意!这不是ac代码!(由于用的邻接矩阵存储边,最后内存超了)

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define maxn 10005
using namespace std;
int raid[maxn][maxn];
int low[maxn],dfn[maxn],sta[maxn],flag[maxn],suo[maxn],indegree[maxn],outdegree[maxn];
int idex=1,number=0,top=0,n,m;//idex时间戳,number强连通分量个数,top sta栈中位置
void tarjan(int u)
{
    int i;
    dfn[u]=low[u]=idex++;//dfn访问的次序,low当前节点能到达的最远的父亲节点的dfn(归入同一强连通分量)
    sta[top++]=u;//入栈
    flag[u]=1;//标记为已访问
    for(int v=1;v<=n;v++)
     {
         if(raid[u][v]) 
        {
             if(!dfn[v])//如果v没有被访问过 
            { 
                tarjan(v);//递归调用
                if(low[u]>low[v])//更新low
                    low[u]=low[v];
            }
            else//被访问过
            {
                if(dfn[v]<low[u]&&flag[v]==1)//v被访问过且v在栈中,防止被弹出的节点被误以为是父亲节点
                {
                    low[u]=dfn[v];//指向父亲节点
                }
            }
        }
    }
    //往后回溯,将栈中属于同一强连通分量的节点全部弹出
    if(dfn[u]==low[u])
        number++;

    do
    {
        i=sta[top];
        flag[i]=0;
        suo[i]=number;//缩点,属于同一强连通分量的节点缩成一个点
        top--;
    }
    while(i!=u);
}
int main()
{
    int t,u,v;
    scanf("%d",&t);
    while(t--)
    {
        number=0;
        idex=1;
        top=0;
        memset(raid,0,sizeof(raid));
        memset(flag,0,sizeof(flag));
        memset(low,0,sizeof(low));
        memset(dfn,0,sizeof(dfn));
        memset(sta,0,sizeof(sta));
        memset(suo,0,sizeof(suo));
        memset(indegree,0,sizeof(indegree));
        memset(outdegree,0,sizeof(outdegree));
         scanf("%d%d",&n,&m);
         for(int i=1;i<=m;i++)
         {
             scanf("%d%d",&u,&v);
             raid[u][v]++;
         }
        int in=0,out=0,MAX=0;//入度和出度
        tarjan(1);//若初始图不一定连通则需要循环调用tarjan函数
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(raid[i][j]!=0&&suo[i]!=suo[j])
                {
                    indegree[suo[j]]++;
                    outdegree[suo[i]]++;
                }
            }
        }
        for(int i=1;i<=number;i++)
        {
            if(indegree[i]==0)
                in++;
            if(outdegree[i]==0)
                out++;
        }
        MAX=max(in,out);
        printf("%d\n",MAX);
    }
    return 0;
}
目录
相关文章
|
5月前
|
存储 算法
数据结构与算法学习二二:图的学习、图的概念、图的深度和广度优先遍历
这篇文章详细介绍了图的概念、表示方式以及深度优先遍历和广度优先遍历的算法实现。
91 1
数据结构与算法学习二二:图的学习、图的概念、图的深度和广度优先遍历
|
2月前
|
负载均衡 算法
架构学习:7种负载均衡算法策略
四层负载均衡包括数据链路层、网络层和应用层负载均衡。数据链路层通过修改MAC地址转发帧;网络层通过改变IP地址实现数据包转发;应用层有多种策略,如轮循、权重轮循、随机、权重随机、一致性哈希、响应速度和最少连接数均衡,确保请求合理分配到服务器,提升性能与稳定性。
342 11
架构学习:7种负载均衡算法策略
|
4月前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
数据结构与算法系列学习之串的定义和基本操作、串的储存结构、基本操作的实现、朴素模式匹配算法、KMP算法等代码举例及图解说明;【含常见的报错问题及其对应的解决方法】你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
2024重生之回溯数据结构与算法系列学习之串(12)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丟脸好嘛?】
|
5月前
|
缓存 算法 Java
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
这篇文章详细介绍了Java虚拟机(JVM)中的垃圾回收机制,包括垃圾的定义、垃圾回收算法、堆内存的逻辑分区、对象的内存分配和回收过程,以及不同垃圾回收器的工作原理和参数设置。
198 4
JVM知识体系学习六:JVM垃圾是什么、GC常用垃圾清除算法、堆内存逻辑分区、栈上分配、对象何时进入老年代、有关老年代新生代的两个问题、常见的垃圾回收器、CMS
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
【EMNLP2024】基于多轮课程学习的大语言模型蒸馏算法 TAPIR
阿里云人工智能平台 PAI 与复旦大学王鹏教授团队合作,在自然语言处理顶级会议 EMNLP 2024 上发表论文《Distilling Instruction-following Abilities of Large Language Models with Task-aware Curriculum Planning》。
|
5月前
|
算法
动态规划算法学习三:0-1背包问题
这篇文章是关于0-1背包问题的动态规划算法详解,包括问题描述、解决步骤、最优子结构性质、状态表示和递推方程、算法设计与分析、计算最优值、算法实现以及对算法缺点的思考。
180 2
动态规划算法学习三:0-1背包问题
|
4月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习(8)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
4月前
|
存储 算法 安全
2024重生之回溯数据结构与算法系列学习之顺序表【无论是王道考研人还真爱粉都能包会的;不然别给我家鸽鸽丢脸好嘛?】
顺序表的定义和基本操作之插入;删除;按值查找;按位查找等具体详解步骤以及举例说明
|
4月前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
4月前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法