zoukankan      html  css  js  c++  java
  • POJ2186 强联通

    题意:
          有一群老牛,给你一些关系,a b表示牛a仰慕牛b,最后问你有多少个牛是被所有牛仰慕的。

    思路:

          假如这些仰慕关系不会出现环,那么当且仅当只有一只牛的出度为0的时候答案才是1,都则就是0,再假设所有的关系正好组成了一个环,那么就是说明每只牛都没其他所有牛仰慕,那么答案就是n,所以我们可以像强联通缩点之后看是否有且仅有一个出度为0的,如果有那么答案就是那个强联通分量的元素个数,否则就是0,因为同一个强联通里面的点有着相同的性质.


    #include<stdio.h>
    #include<string.h>
    #include<stack>
    
    #define N_node 10000 + 100
    #define N_edge 50000 + 500
    
    using namespace std;
    
    typedef struct
    {
       int to ,next;
    }STAR;
    
    typedef struct
    {
       int a ,b;
    }EDGE;
    
    STAR E1[N_edge] ,E2[N_edge];
    EDGE edge[N_edge];
    int list1[N_node] ,list2[N_node] ,tot;
    int Belong[N_node] ,cont;
    int out[N_node] ,sum[N_node];
    int mark[N_node];
    stack<int>st;
    
    void add(int a ,int b)
    {
        E1[++tot].to = b;
        E1[tot].next = list1[a];
        list1[a] = tot;
        E2[tot].to = a;
        E2[tot].next = list2[b];
        list2[b] = tot;
    }
    
    void DFS1(int s)
    {
        mark[s] = 1;
        for(int k = list1[s] ;k ;k = E1[k].next)
        {
           int to = E1[k].to;
           if(!mark[to])DFS1(to);
        }
        st.push(s);
    }
    
    void DFS2(int s)
    {
       Belong[s] = cont;
       sum[cont] ++;
       mark[s] = 1;
       for(int k = list2[s] ;k ;k = E2[k].next)
       {
          int to = E2[k].to;
          if(!mark[to]) DFS2(to);
       }
    }
    
    int main ()
    {
       int n ,m ,a ,b ,i;
       while(~scanf("%d %d" ,&n ,&m))
       {
           memset(list1 ,0 ,sizeof(list1));
           memset(list2 ,0 ,sizeof(list2));
           tot = 1;
           for(i = 1 ;i <= m ;i ++)
           {
               scanf("%d %d" ,&a ,&b);
               add(a ,b);
               edge[i].a = a;
               edge[i].b = b;
           }
           while(!st.empty())
           st.pop();
           memset(mark ,0 ,sizeof(mark));
           for(i = 1 ;i <= n ;i ++)
           if(!mark[i])DFS1(i); 
           cont = 0;
           memset(mark ,0 ,sizeof(mark));
           memset(sum ,0 ,sizeof(sum));
           while(!st.empty())
           {
              int to = st.top();
              st.pop();
              if(!mark[to])
              {
                  cont ++;
                  DFS2(to);
              }
           }
           memset(out ,0 ,sizeof(out));
           for(i = 1 ;i <= m ;i ++)
           {
               a = Belong[edge[i].a];
               b = Belong[edge[i].b];
               if(a == b) continue;
               out[a] ++;
           }
           int ss = 0 ,mk = -1;
           for(i = 1 ;i <= cont ;i ++)
           {
              if(!out[i])
              {
                 ss ++;
                 mk = i;
              }
           }
           if(ss == 1) printf("%d
    " ,sum[mk]);
           else printf("0
    ");
       }
       return 0;
    }
        
       

  • 相关阅读:
    开篇之作
    瀑布流特效
    随写
    关于冒泡排序的补充
    New start-开始我的学习记录吧
    java中序列化的简单认识
    我的Python之路
    算法学习笔记
    Leaflet个人封装笔记
    反射获取config实体类属性并赋值
  • 原文地址:https://www.cnblogs.com/csnd/p/12063049.html
Copyright © 2011-2022 走看看