强连通分量targin算法 洛谷2863

这个坑有点大,刚学oi的蒟蒻其实稍微有点没看懂targin的原理,但是在深搜中,强连通分量一定在同一个子树里肯定是对的,那么接下来直接附上代码吧(之后填坑)

#include<stdio.h>
#include<stdlib.h>
int vis1[100001]={0},nxt[100001]={0},head[100001]={0},low[100001]={0},st[100001]={0},dfn[100001]={0};
int to[100001]={0},co[100001]={0},numcol[100001]={0};
int n,m,num=0,tmp=0,top=0,col=0;
int min(int x,int y)
{
    if(x>y)
      return y;
    else return x;
}
int add(int x,int y)
{
    tmp++;
    nxt[tmp]=head[x];
    to[tmp]=y;
    head[x]=tmp;
    return 0;
}
int targin(int u)
{
    int i,v;
    num++;vis1[u]=1;
    dfn[u]=num;low[u]=num;
    top++;
    st[top]=u;
    for(i=head[u];i;i=nxt[i])
      {
      v=to[i];
      if(dfn[v]==0)
        {
        targin(v);
        low[u]=min(low[u],low[v]);
        }
      else if(co[v]==0)
        low[u]=min(low[u],low[v]);
      }
    if(low[u]==dfn[u])
      {
      col++;
      co[u]=col;
      numcol[col]++;
      while(st[top]!=u)
        {
        co[st[top]]=col;
        numcol[col]++;
        top--;
        }
      top--;
      }
}
int main()
{
    int i,x,y,ans=0;
    scanf("%d%d",&n,&m);
    for(i=1;i<=m;i++)
      {
      scanf("%d%d",&x,&y);
      add(x,y);
      }
    for(i=1;i<=n;i++)
      if(vis1[i]==0)
        targin(i);
    for(i=1;i<=col;i++)
      if(numcol[i]>=2)
        ans++;
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40892508/article/details/82670857