强连通分量Tarjan

Tarjan——求有向图的强连通分量 强连通:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。 [vi-vj之间可以经过多个节点]强连通图:如果有向图G的每两个顶点都强连通,称G是一个强连通图。强连通分量:非强连通图有向图的极大强连通子图,称为强连通分量(strongly connected compone 阅读详情

参考博客:浅析强连通分量(Tarjan和kosaraju)

                Tarjan·关于图的连通性 & 连通分量

题目:1332 上白泽慧音

代码:

#include<bits/stdc++.h>
using namespace std;

const int maxn = 5010;
const int N =  50010;
stack<int>s;
int n, m, idx = 0, k = 1, Bcnt = 0;
int head[N];
int ins[maxn];
int dfn[maxn], low[maxn];
int belong[maxn];
set<int>g[maxn];
set<int>::iterator it;
int ans = 0;
struct edge
{
    int v, next;
} e[N];
void add(int u, int v)
{
    e[k].v = v;
    e[k].next = head[u];
    head[u] = k++;
}
void tarjan(int u)
{
    int v;
    dfn[u] = low[u] = ++idx;
    ins[u] = 1;
    s.push(u);
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v])low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        Bcnt++;
        do
        {
            v = s.top();
            s.pop();
            ins[v] = 0;
            g[Bcnt].insert(v);
        }
        while(u != v);
        int  f = g[Bcnt].size();
        ans = max(f, ans);
    }
}
void init()
{
    idx = 0, k = 1, Bcnt = 0, ans = 0;
    memset(ins, 0, sizeof(ins));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0,sizeof(low));
    memset(head, -1, sizeof(head));
}
int main()
{
    int T, p, u, v, choose;
    init();
    scanf("%d %d", &n, &p);
    for(int i = 1; i <= p; i++)
    {
        scanf("%d %d %d", &u, &v, &choose);
        add(u, v);
        if(choose == 2)add(v, u);
    }
    for(int i= 1; i <= n; i++)if(!dfn[i])tarjan(i);
    int mi = INT_MAX, pos = 0;
    cout<<ans<<endl;
    for(int i = 1; i <= Bcnt; i++)
    {
        if(g[i].size() == ans)
        {
            int first_num = *(g[i].begin());
            if(mi > first_num)
            {
                pos = i;
                mi = first_num;
            }
        }
    }
    int t = 0;
    for(it = g[pos].begin(); it != g[pos].end(); it++)
    {
        if(t != 0)cout<<" ";
        printf("%d", *it);
        t++;
    }
    cout<<endl;
    return 0;
}

题目:Popular Cows    POJ - 2186 

题意:就是有N头牛,给你M中关系,问你有多少头牛受欢迎,当一个牛被除了自己本身的所有牛喜欢那么这头牛就是最受欢迎的牛。

题解:本题采用Tarjan+缩点,把强连通分量看成一个点,统计出度为0的点有多少个,如果出度为0的点为一个的话,那么则这个点(可能是强连通分量缩的点)就是最受欢的,输出这个点包含多少头牛。如果出度为0的点有两个以上,那么就不存在最受欢迎的牛。

代码:

#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 10010;
const int N = 50010;
stack<int>s;
int n, m, idx = 0, k = 1, Bcnt = 0;
int head[N];
int ins[maxn];
int dfn[maxn], low[maxn];
int belong[maxn];
int num[maxn];
int degree[maxn];

struct edge
{
    int v, next;
} e[N];
void add(int u, int v)
{
    e[k].v = v;
    e[k].next = head[u];
    head[u] = k++;
}
void tarjan(int u)
{
    int v;
    dfn[u] = low[u] = ++idx;
    ins[u] = 1;
    s.push(u);
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v])low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        Bcnt++;
        do
        {
            v = s.top();
            s.pop();
            ins[v] = 0;
            belong[v] = Bcnt;
            num[Bcnt]++;

        }
        while(u != v);
    }
}
void init()
{
    idx = 0, k = 1, Bcnt = 0;
    memset(ins, 0, sizeof(ins));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0,sizeof(low));
    memset(head, -1, sizeof(head));
    memset(num, 0, sizeof(num));
    memset(belong , 0, sizeof(belong));
    memset(degree, 0, sizeof(degree));
}
int main()
{
    int T, p, u, v, choose;
    init();
    scanf("%d %d", &n, &p);
    for(int i = 1; i <= p; i++)
    {
        scanf("%d %d", &u, &v);
        add(u, v);
    }
    for(int i= 1; i <= n; i++)if(!dfn[i])tarjan(i);
    for(int i = 1; i <= n; i++){
        for(int j = head[i]; j != -1; j = e[j].next){
            int v = e[j].v;
            if(belong[i] != belong[v]){
                degree[belong[i]]++;
            }
        }
    }
    int flag = 0, pos = 0;
    for(int i = 1; i <= Bcnt; i++){
        if(degree[i] == 0){
                flag++;
                pos = i;
        }
    }
    if(flag > 1)printf("0\n");
    else printf("%d\n", num[pos]);
    return 0;
}


题目:P2863 [USACO06JAN]牛的舞会The Cow Prom

代码:

#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 10010;
const int N = 50010;
stack<int>s;
int n, m, idx = 0, k = 1, Bcnt = 0;
int head[N];
int ins[maxn];
int dfn[maxn], low[maxn];
int belong[maxn];
int num[maxn];

struct edge
{
    int v, next;
} e[N];
void add(int u, int v)
{
    e[k].v = v;
    e[k].next = head[u];
    head[u] = k++;
}
void tarjan(int u)
{
    int v;
    dfn[u] = low[u] = ++idx;
    ins[u] = 1;
    s.push(u);
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v])low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        Bcnt++;
        do
        {
            v = s.top();
            s.pop();
            ins[v] = 0;
            belong[v] = Bcnt;
            num[Bcnt]++;

        }
        while(u != v);
    }
}
void init()
{
    idx = 0, k = 1, Bcnt = 0;
    memset(ins, 0, sizeof(ins));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0,sizeof(low));
    memset(head, -1, sizeof(head));
    memset(num, 0, sizeof(num));
    memset(belong, 0, sizeof(belong));
}
int main()
{
    int T, p, u, v, choose;
    init();
    scanf("%d %d", &n, &p);
    for(int i = 1; i <= p; i++)
    {
        scanf("%d %d", &u, &v);
        add(u, v);
    }
    for(int i= 1; i <= n; i++)if(!dfn[i])tarjan(i);
    int ans = 0;
    for(int i = 1; i <= Bcnt; i++)
    {
        if(num[i] > 1)ans++;
    }
    printf("%d\n", ans);
    return 0;
}


缩点:

题目:P3387 【模板】缩点

代码:

#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 10010;
const int N = 500100;
stack<int>s;
int n, m, idx = 0, k = 1, Bcnt = 0, cn = 0, ans;
int head[N], head1[N];
int ins[maxn];
int dfn[maxn], low[maxn];
int belong[maxn], point[maxn], w[maxn], degree[maxn];
int dis[maxn];

struct edge
{
    int v, next;
} e[N];
struct edge_
{
    int v, next;
} e_[N];
void add(int u, int v)
{
    e[k].v = v;
    e[k].next = head[u];
    head[u] = k++;
}
void add_(int u, int v)
{
    e_[cn].v = v;
    e_[cn].next = head1[u];
    head1[u] = cn++;
}
void tarjan(int u)//强连通分量
{
    int v;
    dfn[u] = low[u] = ++idx;
    ins[u] = 1;
    s.push(u);
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v])low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        Bcnt++;
        do
        {
            v = s.top();
            s.pop();
            ins[v] = 0;
            belong[v] = Bcnt;
        }
        while(u != v);
    }
}
void init()
{
    idx = 0, k = 1, Bcnt = 0, cn = 1, ans = -1;
    memset(head1, -1,sizeof(head1));
    memset(head, -1, sizeof(head));

}
void TopSort()//拓扑排序
{
     queue<int>q;
     for(int i = 1; i <= Bcnt; i++){
        if(!degree[i])q.push(i);
        dis[i] = w[i];
     }
     while(!q.empty()){
        int x = q.front();
        q.pop();
        for(int i = head1[x]; i != -1; i = e_[i].next){
            int v = e_[i].v;
            dis[v] = max(dis[v], dis[x]+w[v]);
            degree[v]--;
            if(degree[v] == 0)q.push(v);
        }
     }
     for(int i = 1; i <= Bcnt; i++){
        ans = max(ans, dis[i]);
     }


}
int main()
{
    int T, p, u, v, choose;
    init();
    scanf("%d %d", &n, &p);
    for(int i = 1; i <= n; i++)
    {
        scanf("%d", &point[i]);
    }
    for(int i = 1; i <= p; i++)
    {
        scanf("%d %d", &u, &v);
        add(u, v);
    }
    for(int i= 1; i <= n; i++)if(!dfn[i])tarjan(i);
    for(int i = 1; i <= n; i++)
    {
        int v;
        for(int j = head[i]; j != -1; j = e[j].next)
        {
            v = e[j].v;
            if(belong[i] != belong[v])//缩点
            {
                add_(belong[i], belong[v]);
                degree[belong[v]]++;
            }
        }
        w[belong[i]] += point[i];
    }
    TopSort();
    printf("%d\n", ans);
    return 0;
}


题目:P1262 间谍网络

思路:本题的思路就是,如果当这个人不能被贿赂并且这个人跟其他人没有关系,那么就是NO。剩下的就是利用缩点,把环缩成一个点,那么这个点的最小值就是整个点的价值。

代码:

#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<algorithm>
using namespace std;
const int maxn = 10010;
const int N = 50010;
const int INF = 1e9+100;
stack<int>s;
int n, m, idx = 0, k = 1, Bcnt = 0;
int head[N];
int ins[maxn];
int dfn[maxn], low[maxn];
int belong[maxn];
int num[maxn];
int degree[maxn], money[maxn];

struct edge
{
    int v, next;
} e[N];
void add(int u, int v)
{
    e[k].v = v;
    e[k].next = head[u];
    head[u] = k++;
}
void tarjan(int u)
{
    int v;
    dfn[u] = low[u] = ++idx;
    ins[u] = 1;
    s.push(u);
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v])low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        Bcnt++;
        do
        {
            v = s.top();
            s.pop();
            ins[v] = 0;
            belong[v] = Bcnt;
            num[Bcnt] = (num[Bcnt], money[v]);//更新环的最小值

        }
        while(u != v);
    }
}
void init()
{
    idx = 0, k = 1, Bcnt = 0;
    memset(ins, 0, sizeof(ins));
    memset(dfn, 0, sizeof(dfn));
    memset(low, 0,sizeof(low));
    memset(head, -1, sizeof(head));
    memset(num, 0, sizeof(num));
    memset(belong, 0, sizeof(belong));
}
int main()
{
    int T, p, u, v, choose;
    init();
    scanf("%d %d", &n, &p);
    for(int i = 1; i <= n; i++)money[i] = INF;
    for(int i = 1; i <= p; i++)
    {
        int pos, val;
        scanf("%d %d", &pos, &val);
        money[pos] = val;
    }
    int m;
    scanf("%d", &m);
    for(int i = 1; i <= m; i++)
    {
        scanf("%d %d", &u, &v);
        add(u, v);
    }
    for(int i= 1; i <= n; i++)if(!dfn[i] && money[i] != INF)tarjan(i);
    for(int i = 1; i <= n; i++)
    {
        if(!dfn[i]) //如果这个人没有被贿赂,或者跟其他人没有关系
        {
            printf("NO\n");
            printf("%d\n", i);
            return 0;
        }
    }
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        for(int j = head[i]; j != -1; j = e[j].next)
        {
            int v = e[j].v;
            if(belong[i] != belong[v])
            {
                degree[belong[v]]++;
            }
        }
    }
    for(int i = 1; i <= Bcnt; i++)
    {
        if(!degree[i]) //利用缩点,找到入度为0的点,
        {
            ans += num[i];
        }
    }
    printf("YES\n");
    printf("%d\n", ans);
    return 0;
}



割点:

题目:P3388 【模板】割点(割顶)

代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 20010;
const int N = 200100;
int head[N];
int dfn[maxn], low[maxn], k = 0, tot = 0, root, cut[maxn];
struct Node
{
    int v, next;
} e[N];
void add(int u, int v)
{
    e[k].v = v;
    e[k].next = head[u];
    head[u] = k++;
}
void Tarjan(int x)
{
    dfn[x] = low[x] = ++tot;
    int flag = 0;
    for(int i = head[x]; i != -1; i = e[i].next)
    {
        int y = e[i].v;
        if(!dfn[y])
        {
            Tarjan(y);
            low[x] = min(low[x], low[y]);
            if(dfn[x] <= low[y] && (x != root || ++flag > 1))cut[x] = 1;
        }
        else low[x] = min(low[x], dfn[y]);
    }
}
int main()
{
    memset(head, -1, sizeof(head));
    int n, m, a, b;
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= m; i++)
    {
        scanf("%d %d", &a, &b);
        add(a, b);
        add(b, a);
    }
    for(int i = 1; i <= n; i++)
    {
        if(!dfn[i])root = i, Tarjan(i);
    }
    int cn = 0;
    for(int i = 1; i <= n; i++)
    {
        if(cut[i])cn++;
    }
    printf("%d\n", cn);
    for(int i =  1; i <= n; i++)
    {
        if(cut[i])printf("%d ", i);
    }
    printf("\n");
}

题目:Network of Schools    POJ - 1236 

思路:第一问就是问你最少给多少人发信息,所以利用缩点,然后寻找入度为0的点就是第一问的答案。第二问,最少增加多少条边,这个图示强联通图,所以就是缩点之后,找到入度和初度为0的最大值。

代码:

#include<stdio.h>
#include<iostream>
#include<stack>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 10010;
const int N = 500100;
stack<int>s;
int n, m, idx = 0, k = 1, Bcnt = 0, cn = 0, ans;
int head[N], head1[N];
int ins[maxn];
int dfn[maxn], low[maxn];
int belong[maxn], in[maxn], out[maxn];

struct edge
{
    int v, next;
} e[N];
struct edge_
{
    int v, next;
} e_[N];
void add(int u, int v)
{
    e[k].v = v;
    e[k].next = head[u];
    head[u] = k++;
}
void add_(int u, int v)
{
    e_[cn].v = v;
    e_[cn].next = head1[u];
    head1[u] = cn++;
}
void tarjan(int u)//强连通分量
{
    int v;
    dfn[u] = low[u] = ++idx;
    ins[u] = 1;
    s.push(u);
    for(int i = head[u]; i != -1; i = e[i].next)
    {
        v = e[i].v;
        if(!dfn[v])
        {
            tarjan(v);
            low[u] = min(low[u], low[v]);
        }
        else if(ins[v])low[u] = min(low[u], dfn[v]);
    }
    if(dfn[u] == low[u])
    {
        Bcnt++;
        do
        {
            v = s.top();
            s.pop();
            ins[v] = 0;
            belong[v] = Bcnt;
        }
        while(u != v);
    }
}
void init()
{
    idx = 0, k = 1, Bcnt = 0, cn = 1, ans = -1;
    memset(head1, -1,sizeof(head1));
    memset(head, -1, sizeof(head));

}

int main()
{
    int T, p, u, v, choose;
    init();
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
    {
        int v;
        while(scanf("%d", &v) && v != 0)
        {
            add(i, v);
        }
    }
    for(int i= 1; i <= n; i++)if(!dfn[i])tarjan(i);
    for(int i = 1; i <= n; i++)
    {
        int v;
        for(int j = head[i]; j != -1; j = e[j].next)
        {
            v = e[j].v;
            if(belong[i] != belong[v])//缩点
            {
                add_(belong[i], belong[v]);
                in[belong[v]]++;
                out[belong[i]]++;
            }
        }
    }
    int ans1 = 0, ans2 = 0;
    for(int i = 1; i <= Bcnt; i++)
    {
        if(!in[i])ans1++;
        if(!out[i])ans2++;
    }
    printf("%d\n", ans1);
    if(Bcnt ==  1)
    {
        printf("0\n");
        return 0;
    }


    ans = max(ans1, ans2);
    printf("%d\n", ans);
    return 0;
}

 

tarjan 算法求强连通分量 转自大牛 全网最详细tarjan算法讲解,我不敢说别的。反正其他tarjan算法讲解,我看了半天才看懂。我写的这个,读完一遍,发现原来tarjan这么简单! tarjan算法,一个关于 图的联通性的神奇算法。基于DFS(迪法师)算法,深度优先搜索一张有向图。!注意!是有向图。根据树,堆栈,打标记等种种神(che)奇(dan)方法来完成剖析一个图的工作。而图的联通性,就是 阅读详情

相关推荐

从MFCC到GMM:手把手教你用Python实现说话人识别(附完整代码)

本文详细介绍了如何使用Python实现说话人识别系统,从MFCC特征提取到GMM模型训练,涵盖完整的技术流程和代码示例。通过梅尔频率倒谱系数(MFCC)和高斯混合模型(GMM)的结合,构建高效的说话人识别系统,适用于身份认证和智能交互场景。文章还探讨了从传统方法到深度学习的进阶话题,如i-vector和x-vector技术。

o1p2q3r的博客 199

图论——强连通分量(Tarjan算法)

一周前写的Tarjan代码遗失了QAQ,趁还没忘,赶紧记录一下。

上总介的博客 4万+

微信小程序消息推送全攻略:从模板消息到订阅消息的实战避坑指南

本文深入解析微信小程序消息推送机制,对比模板消息、订阅消息与客服消息的核心差异与适用场景。重点提供订阅消息从用户授权设计、前端代码实现到后端稳定发送的完整实战指南,并分享提升消息点击率的文案与运营技巧,帮助开发者构建高效、用户友好的消息推送体系。

b3n4m5q6w7的博客 335

强连通分量-tarjan算法缩点

强连通分量:在有向图G中,如果两个顶点u,v间(u->v)有一条从u到v的有向路径,同时还有一条从v到u的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量。简单点说就是:如果一个有向图中,存在一条回路,所有的结点至少被经过一次,这样的图为强连通图。在强连图图的基础上加入一些点和路径,使得当前的图不在强连通,称原来的强连通的部分为强连通分量。

c__chong的博客 3501

西门子S7通信协议TSAP配置全攻略:从默认值到自定义修改(附各型号对照表)

本文深入解析西门子S7通信协议中TSAP配置的核心原理与实战方法。针对S7-200/300/400/1200/1500等主流PLC型号,提供了默认TSAP对照表,并详细阐述了如何根据机架号和插槽号计算或自定义Remote TSAP。文章结合常见连接失败案例,给出了系统化的排错流程,旨在帮助工程师快速打通S7通信链路,提升工业自动化现场调试效率。

weixin_29163797的博客 277

Autosar软件组件分析及ARXML文件分析

Autosar软件组件分析及ARXML文件分析

专注汽车软件开发、AutoSAR、车载以太网、SOA、EE架构。 3600

详解tarjan求强联通分量

tarjan算法是在有向图中求强联通分量的一种算法,基于dfs 其中最重要的需要维护的两个数组是low[maxn],dfn[maxn] low[u]代表u可以到达的最近节点,dfn[u]代表u在dfs树中的深度 其原理是 1.若一个点u是强联通分量的根节点,那么这个点在dfs中的遍历顺序dfn[u]的大小一定会等于它可以到达的最小节点的遍历顺序low[u],即这个点最短只能自己到自己 2.若一个点...

AndrewLi的博客 642

利用人工神经网络在Abaqus中实现本构模型的网格粗化计算框架:详细指南与实践

在这篇文章中,我们详细介绍了如何在Abaqus中实现基于人工神经网络(ANN)的本构模型以进行网格粗化的计算框架。我们通过两个主要模块——数据生成器模块和ANN训练模块,实现了这一计算框架,并将训练好的ANN集成到Abaqus的用户材料子程序(UMAT)中,创建了一个基于ANN的本构模型。我希望这篇文章能帮助到那些希望在Abaqus中实现基于ANN的本构模型的读者,同时,我也非常欢迎大家提出宝贵的意见和建议,让我们共同进步。

qq_38334677的博客 1714

图论学习笔记(6):Tarjan算法(强连通分量/缩点)

Tarjan算法是一种求解有向图中强连通分量的经典算法,其核心思想是基于深度优先搜索,来求有向图的强连通分量的算法。变量名变量类型变量作用g[1010]用于构造图,存每个顶点对应得边ststack<int>用于在深度优先搜索得时候存访问的节点b[1010]bool状态数组,用于判断对于顶点是否入栈tempint时间戳,用于给顶点分配次序号dfn[1010]int节点被搜索的次序号数组,用于记录节点是第几个被深度优先搜索访问的low[1010]int。

m0_74707185的博客 2709

Fabric V2.5 通用溯源系统——使用Hyperledger Caliper压力测试

Caliper是一款测试区块链性能的工具,支持Hyperledger Fabric、Ethereum等,支持丰富的测试配置参数,测试完成后将直接输出报告,相较于tape更加专业,但是配置稍微有些复杂。本文将一步一步配置Caliper以测试Fabric V2.5 通用溯源系统中的注册用户、查询用户、农产品上链、农产品查询的区块链性能。

TrueTechLabs 官方博客 1395

28、数字电路测试与半导体内存测试全解析

本文全面解析了数字电路中的顺序电路测试生成方法与半导体内存测试技术。内容涵盖顺序电路中的故障检测、多重观察测试、可驱动性分析、伪组合电路测试及初始化问题,并深入探讨了内存技术发展、故障模型、测试流程与未来趋势。重点介绍了DRAM、SRAM等主流内存类型的特点,以及制造和使用过程中面临的永久性与非永久性故障挑战,提出了基于故障模型的高效测试策略与优化方案。

go5gopher的博客 122

强联通分量——tarjan算法

tarjan算法求强连通分量数量 一、概念: 1、强连通: 在一个有向图G里,设两个点a b发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,b)强连通。 2、强连通图: 如果在一个有向图G中,每两个点都强连通,我们就叫这个图为强连通图。 3、强连通分量: 在一个有向图G中,有一个子图,这个子图每2个点都满足强连通,我们就叫这个子图叫做强连通分量 举个栗子: 在上图...

luogu_bling的博客 1228

免费教你快速学会分析运算放大器电路(保证学会)

本文旨在学习如何快速简单地对运算放大器进行分析

一名热爱技术的工程师的博客。分享技术干货,记录美好生活。永远相信美好的事情即将发生。 1万+

强连通分量及缩点tarjan算法解析

强连通分量: 简言之 就是找环(每条边只走一次,两两可达) 孤立的一个点也是一个连通分量   使用tarjan算法 在嵌套的多个环中优先得到最大环( 最小环就是每个孤立点)   定义: int Time, DFN[N], Low[N]; DFN[i]表示 遍历到 i 点时是第几次dfs Low[u] 表示 以u点为父节点的 子树 能连接到 [栈中] 最上端的点   int

九野的博客 72万+

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

强连通分量(Tarjan算法)

强连通分量 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量。 Tarjan 算法是基于对图优先搜素的算法 , 每个强连通分量为搜索树中的一棵子树...

森宝的博客 8235

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Tarjan求强连通分量

[算法定义] 在有向图中,如果两个顶点至少存在一条路径(可以相互通达),则称两个顶点强连通(strongly connected)。 如果有向图G的每两个顶点都强连通,称G是一个强连通图。 非强连通有向图的极大强连通子图,称为强连通分量(strongly connected components)。 在上图中,{1 , 2 , 3 , 4 } , { 5 } , { 6 } 三个区域...

weixin_44959460的博客 5280

STM32F407中文手册

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

两种强连通分量算法——tarjan和kosaraju

这两个算法其实都非常简单,其中tarjan算法只需进行一次dfs,更为高效。但我更喜欢kosaraju算法,因为这个算法的思考过程更加巧妙。 tarjan算法的思想非常简单直观,随便找篇教程就很容易理解,下面我主要讲讲kosaraju算法。 kosaraju算法进行两次dfs,第一次在原图上进行,并在结点递归调用返回时将结点压入一个栈中,第二次dfs在原图的逆图上进行,并且初始点选择栈中最上面

cgjiayou 6093

强连通分量 Tarjan

强连通分量 Tarjan 前言 其实很早就会用Tarjan打强连通了,但还是有些一知半解,也忘性大,现在总结一下。 强连通分量的定义 假设我们现在有这个图: 很显然这三个点两两之间可以到达,那么我们就称这个图是强连通的。 假设我们多加一个节点 之前的子图强连通,但不是强联通分量,因为它不是最大的强连通子图,而{1,2,3,4}是强连通分量。一个图可能有多个强连通分量,但我们找强连通一定要找尽可...

Cass-ette的博客 544

Tarjan 强连通分量

强连通分量 图中找到一个最大的子图,使得子图中任意两个节点相互到达。 一个点也是一个强连通分量 Tarjan 构成强连通分量是必定是dfs树的一棵子树,在对树进行dfs的时候记录访问时间dfn和以该节点为根节点的子树的最小编号low,将节点加入栈中并递归它的子节点,子节点在栈中更新根节点的low,子节点没有访问过就继续递归下去。 在回溯的时候,当dfn == low 表示改点可以通过栈中的节点...

Running Bit. 643

强连通分量(Tarjan算法) 图解

最详细的tarjan图解!

qq_25930891的博客 7009

Tarjan找强连通分量

概念 强连通 如果在一张图中有一条路径连接两点,则这两点强连通。(间接连接也可以)(主要针对单向图) 强连通图 如果一张图中任意两点都强连通,则这张图为强连通土。 强连通分量 如果一张图的某个子图为强连通图,则称其为强连通分量。 算法思路 该算法主要用于有向图。对于每一个点,赋予两个属性:dfn和low。dnf记录该点被访问的次序。low记录与该点联通的所有点的dfn的最小值。对访问每一个点时: ...

Edith_Finch的博客 310

Tarjan算法——求强连通分量

什么是强连通分量 强连通分量,是一个有向图的最大强连通子图(看起来好像没有什么解释效果…),好吧,强连通分量就是在一个有向图中,从任意一个点出发,最多可以走过的所有的点构成的一个点集,将其称之为强连通。强连通分量就是这些集合里面最大的那个。如下图: 2,3,5,就是强连通的,因为从二出发可以到达2,3,5的任意一个点。所以1,4,也是强连通的。我们不难发现,除了双向边以外,强连通都是环套环的形式...

Martisum的博客 3511

图论算法-Tarjan之强连通分量

Tarjan--强连通分量

weixin_49289750的博客 1487

SCC-Tarjan算法,强连通分量算法,从dfs到Tarjan详解

如何一步步从dfs到tarjan算法?

EQUINOX1的博客 2638

强连通分量个数的tarjan算法

/* 强连通分量个数tarjan算法 */ #include #include #include #include using namespace std; const int maxV=1000,maxE=1000000; struct Edge { int to,next; }edge[maxE]; int Adj[maxV],Size; void ini

码代码的猿猿 1604
上一篇: As rich as Crassus(扩展中国剩余定理)
下一篇: Little Sub and Triangles(叉积+二分查找)
Re:fused
博客等级 码龄9年 474粉丝 162原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值