• 最近切的两题SCC的tarjan POJ1236 POJ2186


    两题都是水题,1236第一问求缩点后入度为0的点数,第二问即至少添加多少条边使全图强连通,属于经典做法,具体可以看白书
    POJ2186即求缩点后出度为0的那个唯一的点所包含的点数(即SCC里有多少点)
    //poj1236
    #include<iostream>
    #include<cstdio>
    #include<string.h>
    #define maxn 6000
    int now=0,next[maxn],head[maxn],point[maxn],num=0,dfn[maxn],low[maxn],instack[maxn];
    int stack[maxn],belong[maxn],top,count,in[maxn],out[maxn];
    int min(int a,int b)
    {
        if (a<b)return a;else return b;
    }
    int max(int a,int b)
    {
        if (a>b)return a;else return b;
    }
    void add(int x,int y)
    {
        next[++now]=head[x];
        head[x]=now;
        point[now]=y;
    }
    void tarjan(int k)
    {
        int u;
        instack[k]=true;
        dfn[k]=low[k]=++num;stack[++top]=k;
        for(int i=head[k];i!=0;i=next[i])
        {
            u=point[i];
            if (dfn[u]==0)
            {
                tarjan(u);
                low[k]=min(low[k],low[u]);
            }
            else if (instack[u])low[k]=min(dfn[u],low[k]);
        }
        if (low[k]==dfn[k])
        {
            ++count;
            do
            {
                u=stack[top--];
                instack[u]=false;
                belong[u]=count;
            }while(u!=k);
        }
    }
    int main()
    {
        int n,t;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)while (1)
        {
            scanf("%d",&t);
            if (t==0)break;
            else add(i,t);
        }
        for(int i=1;i<=n;i++)if (dfn[i]==0)tarjan(i);
        for(int i=1;i<=n;i++)
        {
            for(int j=head[i];j!=0;j=next[j])
            {
                int u=point[j];
                if (belong[i]!=belong[u])
                {
                    out[belong[i]]++;
                    in[belong[u]]++;
                }
            }
        }
        int countout=0,countin=0;
        for(int i=1;i<=count;i++)
        {
            if (out[i]==0)countout++;
            if (in[i]==0)countin++;
        }
        if (count==1)printf("1
    0
    ");
        else printf("%d
    %d
    ",countin,max(countout,countin));
        return 0;
    }
     

    //poj2186

    #include<iostream>

    #include<cstdio>

    #include<string.h>

    #define maxn 50010

    using namespace std;

    intnow=0,next[maxn],head[maxn],point[maxn],num=0,dfn[maxn],low[maxn],instack[maxn];

    int stack[maxn],belong[maxn],top,count,out[maxn],p[maxn];

    void add(int x,int y)

    {

        next[++now]=head[x];

        head[x]=now;

        point[now]=y;

    }

    void tarjan(int k)

    {

        instack[k]=1;

        stack[++top]=k;

        low[k]=dfn[k]=++num;

        int u;

        for(inti=head[k];i!=0;i=next[i])

        {

            u=point[i];

            if (dfn[u]==0)

            {

                tarjan(u);

               low[k]=min(low[u],low[k]);

            }

            else if (instack[u]==1)low[k]=min(dfn[u],low[k]);

        }

        if (low[k]==dfn[k])

        {

            ++count;

            do

            {

                u=stack[top--];

                instack[u]=0;

                belong[u]=count;

                p[count]++;

            }while(u!=k);

        }

    }

    int main()

    {

        int n,m,x,y,ans=0;

       scanf("%d%d",&n,&m);

        for(int i=1;i<=m;i++)

        {

           scanf("%d%d",&x,&y);

            add(x,y);

        }

        for(int i=1;i<=n;i++)

        if (dfn[i]==0)tarjan(i);

        for(int i=1;i<=n;i++)

        {

            for(int j=head[i];j!=0;j=next[j])

            {

                int u=point[j];

                if(belong[i]!=belong[u])out[belong[i]]++;

            }

        }

        int flag=0;

        for(inti=1;i<=count;i++)

        {

            if (ans!=0 &&out[i]==0){flag=1;break;}

            if(out[i]==0)ans=p[i];

        }

        if(flag==0)printf("%d ",ans);else printf("0 ");

        return 0;

    }

  • 相关阅读:
    Linux Shell tr 命令详解
    Shell统计每个单词出现的个数
    启明4-29团队进度博客
    启明4-28团队进度博客
    启明4-27团队进度博客
    启明4-26团队进度博客
    启明4-25团队进度博客
    启明4-24团队博客
    每日总结8
    启明4-23团队进度博客
  • 原文地址:https://www.cnblogs.com/philippica/p/4006995.html
Copyright © 2020-2023  润新知