• tarjan模板


    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<stack> 
    #include<vector> 
    using namespace std;
    const int maxn=50010;
    int first[maxn],to[maxn],next[maxn],cnt,from[maxn];
    void add(int u,int v)
    {
        from[++cnt]=u;
        to[cnt]=v;
        next[cnt]=first[u];
        first[u]=cnt;
    }
    int dfn[maxn],low[maxn],vis[maxn],ind,scc,now,st[maxn],top;
    int isc[maxn];
    vector<int> bl[maxn];
    int blc;
    int tag[maxn];
    void Tarjan_dfs(int x,int fa)
    {
        int son=0;
        low[x]=dfn[x]=++ind;
        for(int i=first[x];i;i=next[i])
        {
            int now=to[i];
            if(!dfn[now])
            {
                st[++top]=i;son++;
                Tarjan_dfs(now,x);
                low[x]=min(low[x],low[now]);
                if(low[now]>=dfn[x])
                {
                    isc[x]=1;
                    bl[++blc].clear();
                    while(1)
                    {
                        int num=st[top--];
                        if(tag[from[num]]!=blc)
                        {
                            bl[blc].push_back(from[num]);
                            tag[from[num]]=blc;
                        }
                        if(tag[to[num]]!=blc)
                        {
                            bl[blc].push_back(to[num]);
                            tag[to[num]]=blc;
                        }
                        if(to[num]==now && from[num]==x)break;
                    }
                }
            }
            else if(dfn[now]<dfn[x] && now!=fa)
            {
                st[++top]=i;
                low[x]=min(low[x],dfn[now]);
            }
        }
        if(fa==0 && son==1)isc[x]=0;
    }
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            add(u,v);
            add(v,u);
        }
        for(int i=1;i<=n;i++)if(!dfn[i])Tarjan_dfs(i,-1);
        cout<<blc<<endl;
        return 0;
    }
    点双联通

    来自韩棒棒,输出点双的数量

    #include<cstdio>
    #include<vector>
    #include<algorithm>
    using namespace std;
    int n,m,order;
    int low[20004],dfn[20004],father[20004],son[20004];
    //father:父结点 son:子结点个数 
    vector<int> edge[20004];
    vector< pair<int,int> > cutedge;
    void tarjan(int u)
    {
        dfn[u]=low[u]=++order;
        for (int i=0;i<edge[u].size();i++)
        {
            int v=edge[u][i];
            if(!dfn[v])
            {
                son[u]++;
                father[v]=u;
                 tarjan(v);
                if(low[v]>dfn[u]) cutedge.push_back(make_pair(min(v,u),max(v,u)));
                //边v-u为割边 
                low[u]=min(low[u],low[v]);
            }
            else if(v!=father[u]) low[u]=min(low[u],dfn[v]);
        }
        //根节点若有两棵或两棵以上的子树则该为割点
        //非根节点若所有子树节点均没有指向u的祖先节点的回边则为割点
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            edge[u].push_back(v),edge[v].push_back(u);
        }
        tarjan(1);
        sort(cutedge.begin(),cutedge.end());
        for(int i=0;i<cutedge.size();i++) printf("%d %d
    ",cutedge[i].first,cutedge[i].second);
    }
    边双

    输出桥,边双就是图删去桥后的联通块

  • 相关阅读:
    arm架构与体系结构
    C语言双链表遍历,插入,删除
    C语言实现单链表的遍历,逆序,插入,删除
    C语言函数的变参实用与分析
    DEBUG宏
    运算中的临时匿名变量
    main函数的传参与返回
    存储类、作用域、生命周期、链接属性
    制作动态链接库并使用
    内存管理——进程创建,执行,缺页,终止
  • 原文地址:https://www.cnblogs.com/wjxgy/p/7761696.html
Copyright © 2020-2023  润新知