zoukankan      html  css  js  c++  java
  • 洛谷 P2863 [USACO06JAN]牛的舞会The Cow Prom(Tarjan)

    一道tarjan的模板水题

    在这里还是着重解释一下tarjan的代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    int n,m;
    int cnt;//记录强联通分量的个数
    int visitnum;//遍历的步数
    int dfn[100010];//记录元素第一次被访问的步数
    int low[100010];//包含i的强联通分量最早被访问的步数
    int num[100010];//记录强联通分量里的点的个数
    int belong[100010];//i从属的强联通分量的序号
    int top;//栈中元素的个数
    int stack[100010];//手打栈
    int instack[100010];//判断元素是否在栈中
    int head[100010];
    struct node{
    int to,next;
    }edge[100010];//链式前向星存边
    int read()//读入优化
    {
        int x=0,w=1;char ch=getchar();
        while(ch>'9'||ch<'0') {if(ch=='-')w=-1;ch=getchar();}
        while(ch<='9'&&ch>='0') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return x*w;
    }
    void tarjan(int);
    int main()
    {
        int ans=0;
        int p,q;
        n=read();m=read();
        for(int i=1;i<=m;i++)
        {
            p=read();q=read();
            edge[i].to=q;
            edge[i].next=head[p];
            head[p]=i;
        }
        for(int i=1;i<=n;i++)
        {
            if(!dfn[i])//i没被访问过了
            {
                tarjan(i);
            }
        }
        for(int i=1;i<=cnt;i++)
        {
            if(num[i]>1)
            ans++;
        }
        printf("%d",ans);
    }
    void tarjan(int u)
    {
        int v;
        visitnum++;
        dfn[u]=low[u]=visitnum;
        stack[++top]=u;//入栈
        instack[u]=1;//入栈
        for(int i=head[u];i;i=edge[i].next)
        {
            v=edge[i].to;
            if(!dfn[v])//还没被访问过
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);//判断u是否为v的子节点
            }
            else if(instack[v])
            {
                low[u]=min(low[u],dfn[v]);
                           //其实这里的dfn[v]也能换成low[v] 但最好写dfn
            }
        }
        if(dfn[u]==low[u])//u为强联通分量的根
        {
            cnt++;
            do//退栈
            {
                num[cnt]++;
                v=stack[top--];
                belong[v]=cnt;
                instack[v]=0;
            }while(u!=v);
        }
    }
    
  • 相关阅读:
    self 和 super 关键字
    NSString类
    函数和对象方法的区别
    求两个数是否互质及最大公约数
    TJU Problem 1644 Reverse Text
    TJU Problem 2520 Quicksum
    TJU Problem 2101 Bullseye
    TJU Problem 2548 Celebrity jeopardy
    poj 2586 Y2K Accounting Bug
    poj 2109 Power of Cryptography
  • 原文地址:https://www.cnblogs.com/lsgjcya/p/9082871.html
Copyright © 2011-2022 走看看