zoukankan      html  css  js  c++  java
  • 连通图 poj2186 最受欢迎的牛(求最受欢迎的牛的数量)

      Popular Cows
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 27531   Accepted: 11077

    Description

    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.

    Source

     
    本题题意时每个牛都可以仰慕求它的牛,而且仰慕关系可以互相传递
    问最受欢迎的牛的数量有多少个
    可以利用强联通的缩点法,最后求缩点之后的初度为0的点的数量,
    注意一个问题就是:
    如果没有出度为0的点,那么结果输出答案为0
    下面提供了几组样例,主要注意的输出为0的点需要特别判断
    解决该题目的模板同上面的那个解决学校之间传递数量文件关系的拿到题所用的模板都是一套模板,而且判断入度出度那里也咩有变化
    ps::附上嗲吗
    #include <string.h>
    #include <stdio.h>
    #define V    10500
    #define E    50500
    
    struct edge
    {
        int to, next;
    }Edge[E];
    int head[V], e, n;
    
    int indeg[V], outdeg[V]; //点的入度和出度数
    int belong[V], low[V], dfn[V], scc, cnt;//dfn[]:遍历到u点的时间; low[]:u点可到达的各点中最小的dfn[v]
    int S[V], top;
    bool vis[V];//v是否在栈中
    
    int addedge(int u, int v)
    {
        Edge[e].to = v;
        Edge[e].next = head[u];
        head[u] = e++;
        return 0;
    }
    void tarjan(int u)
    {
        int v;
        dfn[u] = low[u] = ++cnt;//开始时dfn[u] == low[u]
        S[top++] = u;//不管三七二十一进栈
        vis[u] = true;
        for (int i=head[u]; i!=-1; i=Edge[i].next)
        {
            v = Edge[i].to;
            if (dfn[v] == 0)//如果v点还未遍历
            {
                tarjan(v);//向下遍历
                low[u] = low[u] < low[v] ? low[u] : low[v];//确保low[u]最小
            }
            else if (vis[v] && low[u] > dfn[v])//v在栈中,修改low[u]
                low[u] = dfn[v];
        }
        if (dfn[u] == low[u])//u为该强连通分量中遍历所成树的根
        {
            ++scc;
            do
            {
                v = S[--top];//栈中所有到u的点都属于该强连通分量,退栈
                vis[v] = false;
                belong[v] = scc;
            } while (u != v);
        }
    
    }
    
    int solve(){
        scc = top = cnt = 0;
        memset(dfn, 0, sizeof(dfn));
        memset(vis, false, sizeof(vis));
        for (int u=1; u<=n; ++u)
            if (dfn[u] == 0)
                tarjan(u);
        return scc;
    }
    
    void count_deg()
    {
        memset(indeg, 0, sizeof(indeg));
        memset(outdeg, 0, sizeof(outdeg));
        for (int u=1; u<=n; ++u)
            for (int i=head[u]; i!=-1; i=Edge[i].next)
            {
                int v = Edge[i].to;
                if (belong[u] != belong[v])
                {
                    indeg[belong[v]]++;
                    outdeg[belong[u]]++;
                }
            }
    }
    
    int main()
    {
        int u, v, i;
        int m;
        while (~scanf("%d%d", &n,&m))
        {
            e = 0;
            memset(head, -1, sizeof(head));
            for (int i=1;i<=m;i++){
                scanf("%d%d",&u,&v);    
                    addedge(u, v);
            }
            solve();
                count_deg();
    
              int num=0,tmp;
            for(int i = 1; i <= scc; i++)  
            {  
                if(!outdeg[i])  
                {  
                    num++;  
                    tmp = i;  
                }  
                      
            }  
              int ans=0;
            if(num == 1)  
            {  
                for(int i = 1; i <= n; i++)  
                {  
                    if(belong[i] == tmp)  
                        ans++;  
                }  
                printf("%d
    ", ans);  
            }  
            else  
            {  
                printf("0
    ");  
            }  
    
            
        }
        return 0;
    }
  • 相关阅读:
    数据可视化 —— 数据流图(Data Flow Diagram)
    TensorFlow 实战(四)—— tensor 的认识
    数据集(benchmark)、常用数据集的解析(cifar-10、)
    HDU--杭电--4504--威威猫系列故事——篮球梦--DP
    android打包apk时混淆遇到的问题
    C语言数据结构----递归的应用(斐波拉契数列、汉诺塔、strlen的递归算法)
    按 Eclipse 开发喜好重新布置 cocos2dx 目录层次
    HDU--杭电--4502--吉哥系列故事——临时工计划--背包--01背包
    (step6.3.2)hdu 1068(Girls and Boys——二分图的最大独立集)
    flashcache中应用device mapper机制
  • 原文地址:https://www.cnblogs.com/13224ACMer/p/4781453.html
Copyright © 2011-2022 走看看