zoukankan      html  css  js  c++  java
  • 图论:强连通分量

    Luogu2863:利用Tarjan求有向图的强连通分量

    强连通分量这这样的一个子图:

    图中的任意两点都可以相互通达,它是有向图

    这里的例题题意是这样的,统计所有强连通分量中,至少包含两个点的强连通分量的数量

    const int maxn=10005;
    const int maxm=50005;
    int n,m,cnt,deep,top,sum,ans;
    int g[maxn],vis[maxn],dfn[maxn<<1],low[maxn<<1],st[maxn<<1],col[maxn],tot[maxn];
    struct Edge{int t,next;}e[maxm];

    这里面把强连通分量的点放在st栈里,用vis进行存在性标记

    col的意思是下标属于哪一个强连通分量,tot是用来统计每一种强连通分量所包含的顶点数量的

    void tarjan(int u)
    {
        dfn[u]=++deep;low[u]=deep;
        vis[u]=1;
        st[++top]=u;
        for(int tmp=g[u];tmp;tmp=e[tmp].next)
        {
            int v=e[tmp].t;
            if(!dfn[v]) {tarjan(v);low[u]=min(low[u],low[v]);}
            else if(vis[v]) low[u]=min(low[u],low[v]);
        }
        if(dfn[u]==low[u])
        {
            col[u]=++sum;vis[u]=0;
            while(st[top]!=u)
            {
                col[st[top]]=sum;
                vis[st[top--]]=0;
            }
            top--;
        }
    }

    这里的Tarjan还是很显然的,与之前的两种大同小异

    最后给出完整的实现:

     1 #include<cstdio>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn=10005;
     5 const int maxm=50005;
     6 int n,m,cnt,deep,top,sum,ans;
     7 int g[maxn],vis[maxn],dfn[maxn<<1],low[maxn<<1],st[maxn<<1],col[maxn],tot[maxn];
     8 struct Edge{int t,next;}e[maxm];
     9 void addedge(int u,int v)
    10 {
    11     e[++cnt].t=v;
    12     e[cnt].next=g[u];g[u]=cnt;
    13 }
    14 void tarjan(int u)
    15 {
    16     dfn[u]=++deep;low[u]=deep;
    17     vis[u]=1;
    18     st[++top]=u;
    19     for(int tmp=g[u];tmp;tmp=e[tmp].next)
    20     {
    21         int v=e[tmp].t;
    22         if(!dfn[v]) {tarjan(v);low[u]=min(low[u],low[v]);}
    23         else if(vis[v]) low[u]=min(low[u],low[v]);
    24     }
    25     if(dfn[u]==low[u])
    26     {
    27         col[u]=++sum;vis[u]=0;
    28         while(st[top]!=u)
    29         {
    30             col[st[top]]=sum;
    31             vis[st[top--]]=0;
    32         }
    33         top--;
    34     }
    35 }
    36 int main()
    37 {
    38     scanf("%d%d",&n,&m);
    39     int u,v;
    40     for(int i=1;i<=m;i++)
    41     {
    42         scanf("%d%d",&u,&v);
    43         addedge(u,v);
    44     }
    45     for(int i=1;i<=n;i++)
    46         if(!dfn[i]) tarjan(i);
    47     for(int i=1;i<=n;i++) tot[col[i]]++;
    48     for(int i=1;i<=sum;i++)
    49         if(tot[i]>1) ans++;
    50     printf("%d
    ",ans);
    51     return 0;
    52 }
  • 相关阅读:
    win7+Apache 设置域名指向本地文件夹
    JavaScript 函数式编程
    JS防抖动
    13 个最佳 JavaScript 数据网格库
    js笔试-接收get请求参数
    这10道javascript笔试题你都会么
    60行JavaScript代码俄罗斯方块
    先少谈点人工智能好吗?
    gulp+webpack构建配置
    Gulp和webpack的区别,是一种工具吗?
  • 原文地址:https://www.cnblogs.com/aininot260/p/9428798.html
Copyright © 2011-2022 走看看