zoukankan      html  css  js  c++  java
  • poj2186强联通(牛仰慕)

    题意:
          有一群老牛,他们之间有m组敬仰关系,关系可以传递,a仰慕b,b仰慕c,那么a就仰慕c,现在问被所有老牛都仰慕
    的有多少?


    思路:

          想想,是不是一个环中的老牛的关系都是一样的,就是只要有一只牛仰慕了环里面的任何一只牛,那么这个环里的所有牛都将被这只牛仰慕,那好,我们进行强联通缩点,然后出度为0的那个连通快就是被所有牛都仰慕的。前提是出度为0的连通快只能有一个才行,否则就输出0.


    #include<stack>
    #include<stdio.h>
    #include<string.h>
    
    #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;
    
    EDGE edge[N_edge];
    STAR E1[N_edge] ,E2[N_edge];
    stack<int>sk;
    int mark[N_node];
    int list1[N_node] ,list2[N_node] ,tot;
    int Belong[N_node] ,Cnt;
    int Cout[N_node];
    
    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)
        if(!mark[E1[k].to])DFS1(E1[k].to);
        sk.push(s);
    }
    
    void DFS2(int s)
    {
        mark[s] = 1;
        Belong[s] = Cnt;
        for(int k = list2[s] ;k ;k = E2[k].next)
        if(!mark[E2[k].to]) DFS2(E2[k].to);
    }
    
    int solve(int n ,int m)
    {
        memset(mark ,0 ,sizeof(mark));
        while(!sk.empty()) sk.pop();
        for(int i = 1 ;i <= n ;i ++)
        if(!mark[i]) DFS1(i);
        Cnt = 0;
        memset(mark ,0 ,sizeof(mark));
        while(!sk.empty())
        {
            int xin = sk.top();
            sk.pop();
            if(mark[xin]) continue;
            ++Cnt;
            DFS2(xin);
        }
        memset(Cout ,0 ,sizeof(Cout));
        for(int i = 1 ;i <= m ;i ++)
        {
            int a = Belong[edge[i].a];
            int b = Belong[edge[i].b];
            if(a==b)continue;
            Cout[a] ++;
        }
        int s = 0;
        for(int i = 1 ;i <= Cnt ;i ++)
        if(!Cout[i]) s ++;
        if(s != 1) return 0;
        s = 0;
        for(int i = 1 ;i <= n ;i ++)
        if(!Cout[Belong[i]]) s ++;
        return s;
    }
    
    int main ()
    {
        int n ,m ,i ,a ,b;
        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;
            }
            printf("%d
    " ,solve(n ,m));
        }
        return 0;
    }
    
    


  • 相关阅读:
    vue开发chrome扩展,数据通过storage对象获取
    Vue手动集成less预编译器
    Google Translate寻找之旅
    Javascript Range对象的学习
    Javascript Promises学习
    SublimeText 建立构建Node js系统
    We're sorry but demo3 doesn't work properly without JavaScript enabled. Please enable it to continue.
    npm安装包出现UNMET DEPENDENCY报错
    (转载)命令行说明中格式 尖括号 中括号的含义
    Linux重启网卡服务Failed to start LSB: Bring up/down networking.
  • 原文地址:https://www.cnblogs.com/csnd/p/12062391.html
Copyright © 2011-2022 走看看