zoukankan      html  css  js  c++  java
  • POJ 2186 白书经典 强连通图分量(内附模板)

    题目:https://vjudge.net/problem/POJ-2186

    Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is
    popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

    Input

    * Line 1: Two space-separated integers, N and M

    * Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

    Output

    * Line 1: A single integer that is the number of cows who are considered popular by every other cow.

    Sample Input

    3 3
    1 2
    2 1
    2 3
    

    Sample Output

    1
    

    Hint

    Cow 3 is the only cow of high popularity.
     
     
    题意:  每头牛都想当红人   给定n头牛的牛群    和m个有序对   (A,B)(B,C)==》(A,C)
         表示A认为B是红人   B认为C是红人  那么就有  A认为C是红人
       求被其它所有牛认为是红人的牛的个数
     
     
    思路:   假如直接遍历每一个顶点搜索的到  复杂度O(n*m)会超时
     
     
               假如  有(A,B) 和(B,A)那么可以把A和B缩成一个点    
     
     
    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<algorithm>
    #include<map>
    #define maxn 200005
    using namespace std;
    bool used[maxn];         //点是否被遍历
    int n,m;                 //顶点数和边数
    vector<int>mp[50005];    //建图数组
    vector<int>mp2[50005];   //反向边建立图
    vector<int>vs;           //后序遍历顺序的顶点列表
    int cmp[maxn];           //强连通分量的拓扑序

    //建立图
    void add_edge(int from,int to)
    {
        mp[from].push_back(to);    //正反建立图
        mp2[to].push_back(from);
    }

    //第一次dfs遍历
    void dfs(int x)
    {
        used[x]=true;  // 标记
        for(int i=0;i<mp[x].size();i++)
        {
            if(!used[mp[x][i]])dfs(mp[x][i]);   //dfs图
        }
        //cout<<x<<endl;
        vs.push_back(x);    //记录遍历的顺序
    }

    //第二次dfs遍历
    void rdfs(int x,int k)
    {
        used[x]=true;  //标记点
        cmp[x] = k;   //记录属于一个集合
        for(int i = 0; i<mp2[x].size(); i ++)
        {
            if(!used[mp2[x][i]])rdfs(mp2[x][i],k);
        }
    }

    //查询模板  计算强连通图的个数
    int scc()
    {
        memset(used,false,sizeof(used));
        vs.clear();
        for(int i = 0;i < n;i ++)
        {
            if(!used[i])dfs(i);
        }
        memset(used,false,sizeof(used));
        int k=0;
        for(int i=vs.size()-1;i>=0;i--)    //从查询顺序和第一次查询顺序相反
        {
            if(!used[vs[i]])rdfs(vs[i],k++);
        }
            return k;
    }

    int a[maxn],b[maxn];
    int main()
    {
        cin>>n>>m;
        for(int i=0;i<m;i++)
        {
            cin>>a[i]>>b[i];
            add_edge(a[i]-1,b[i]-1);
        }
        int ans=scc();
        int flag=0;
        int num=0;
        //cout<<ans<<endl;
        for(int i=0;i<n;i++)
        {
            if(cmp[i]==ans-1)
            {
                flag=i;
                num++;
            }
        }
       // cout<<flag<<endl;
       //cout<<num<<endl;
        //检查是否从所有点可达
        memset(used,false,sizeof(used));
        rdfs(flag,0);     //重新用强连通分量分解的代码
        for(int i=0;i<n;i++)
        {
            if(!used[i]){
                num=0;
            break;
            }
        }
        cout<<num<<endl;
         return 0;
    }

    /*

    12 16
    2 3
    3 2
    4 3
    4 1
    5 7
    6 3
    6 4
    6 5
    7 6
    8 10
    9 8
    9 7
    10 9
    11 8
    11 10
    12 11

    0

    */

     
     
     
     
     
               
  • 相关阅读:
    scan chain的原理和实现——3.Tester Timing
    pattern——serial/paralel
    Scan and ATPG (Tessent)----1.基础概念
    ipdb介绍及Tensor
    pytorch简介
    Python 之map、filter、reduce
    分类器、logistic回归
    机器学习方法、距离度量、K_Means
    动态规划、图
    T分布
  • 原文地址:https://www.cnblogs.com/huangzzz/p/8858807.html
Copyright © 2011-2022 走看看