zoukankan      html  css  js  c++  java
  • 【洛谷2661】信息传递 强联通分量

    分析

    tarjan算出全部的联通块,在求出联通块里最小的个数。

    AC代码

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <cctype>
    #include <cmath>
    #include <time.h>
     
    using namespace std;
     
    #define ms(a,b) memset(a,b,sizeof(a))
     
    const int maxn=200010;
     
    struct Edge{
        int to,next;
    }edge[maxn<<1];
     
    int nedge,sum,dep,top,n,m,cnt;
    int head[maxn],dfn[maxn],stack[maxn],low[maxn],od[maxn],vis[maxn],id[maxn];
    int belong[maxn],block[maxn];
     
    inline int read()
    {
        int X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
     
    void add_edge(int a,int b)
    {
        edge[nedge]=(Edge){b,head[a]}; head[a]=nedge++;
    }
     
    void tarjan(int u)
    {
        dfn[u]=low[u]=++dep;
        stack[top++]=u;
        vis[u]=1;
        for (int i=head[u];i!=-1;i=edge[i].next)
        {
            int v=edge[i].to;
            if (!dfn[v]) 
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else
            {
                if (vis[v]) low[u]=min(low[u],dfn[v]);
            }
        }
        int j;
        if (dfn[u]==low[u])
        {
            sum++;
            do{
                j=stack[--top];
                belong[j]=sum;
                vis[j]=0;
            }
            while (u!=j);
        }
    }
     
    int main()
    {
        nedge=0;
        ms(head,-1);
        n=read();
        for (int i=1;i<=n;i++)
        {
            int a=read();
            add_edge(i,a);
        }
        for (int i=1;i<=n;i++)
        {
            if (!dfn[i]) tarjan(i);
        }
        for (int i=1;i<=n;i++)
        {
            block[belong[i]]++;
        }
        int ans=maxn;
        for (int i=1;i<=sum;i++)
        {
            if (block[i]!=1) ans=min(block[i],ans);
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    LeetCode Ugly Number
    LeetCode Missing Number
    拓扑排序
    不相交集的求并算法(按集合大小求并+按高度求并)
    数据结构排序总结
    基数排序
    java 发展简史
    java 白皮书的关键术语
    包+类导入+静态导入+类放入包中+包作用域
    关于二叉堆(优先队列)的其他操作及其应用
  • 原文地址:https://www.cnblogs.com/Dawn-Star/p/9734777.html
Copyright © 2011-2022 走看看