• bzoj1051[kosaraju算法]求强连通分量


    之前一直用的是tarjan第一次学习到这个来试一下。

    唔,就是裸的算法,然后如果出度为0的点只有一个,输出这个点的大小。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<stack>
    #define mm 200004
    #define mn 10020
    using namespace std;
    stack<int>s;
    queue<int>q;
    struct ding{
      int to,next,sum;
    }edge[mm],edge2[mm];
    struct ding2{
      int xx,yy;
    }a[mm];
    int vis[mn],now[mn],ans,head[mn],head2[mn],node[mn],size[mn],num;
    int ru[mn],n,m,vv;
    bool cmp(ding2 k1,ding2 k2)
    {return (node[k1.xx]==node[k2.xx]?node[k1.yy]<node[k2.yy]:node[k1.xx]<node[k2.xx]);}
    void dfs(int x)
    {
      if (vis[x]) return;
      vis[x]=true;
      for (int i=head[x];i;i=edge[i].next) dfs(edge[i].to);
      s.push(x);
    }
    void redfs(int x)
    {
      if (node[x]) return;
      node[x]=num; size[num]++;
      for (int i=head2[x];i;i=edge2[i].next) 
      redfs(edge2[i].to);
    }
    void add(int u,int v,ding*g,int*f)
    {
      int p=++g[0].sum;
      g[p].to=v; g[p].next=f[u];f[u]=p;    
    }
    int main()
    {
      //freopen("cow4.in","r",stdin);
      //freopen("cow4.out","w",stdout);
      scanf("%d%d",&n,&m);
      for (int i=1;i<=m;i++)
      {
          scanf("%d%d",&a[i].xx,&a[i].yy);
          add(a[i].xx,a[i].yy,edge,head);add(a[i].yy,a[i].xx,edge2,head2);
      }
      for (int i=1;i<=n;i++) if (!vis[i])dfs(i);
      while (!s.empty())
      {
          if (!node[s.top()]) {num++; redfs(s.top());}
          s.pop();
      }
      for (int i=1;i<=m;i++) if (node[a[i].xx]>node[a[i].yy])
      {
          int t=a[i].xx;
          a[i].xx=a[i].yy;
          a[i].yy=t;
      }
      sort(a+1,a+1+m,cmp);
      int t1=0,t2=0;
      for (int i=1;i<=m;i++)
       { 
          if ((node[a[i].xx]==t1)&&(node[a[i].yy]==t2)
          ||(node[a[i].xx]==node[a[i].yy])) continue;
        t1=node[a[i].xx];t2=node[a[i].yy];
        ru[t1]++;
       }
      for (int i=1;i<=num;i++) 
      if (ru[i]==0) ans=size[i],vv++;  
      if (vv==1) printf("%d
    ",ans);
      else printf("0
    ");
      return 0;
    }
  • 相关阅读:
    为什么你投十份简历,只有一两家公司约你?又或者为什么你每投一份简历都能获得面试机会?
    JAVA程序1,1,2,3,5,8,13,21....第30个是什么...?
    1-2+3-4+5-6+7......+n的几种实现
    分层应用——如何实现登录?
    初识三层
    VB.NET视频总结——后续篇
    操作系统小结
    VB.NET视频总结——基础篇
    台湾与大陆的计算机术语翻译差异
    VB.NET概述
  • 原文地址:https://www.cnblogs.com/2014nhc/p/7598867.html
Copyright © 2020-2023  润新知