• POJ2186 (强连通分量缩点后出度为0的分量内点个数)


    Popular Cows
    Time Limit: 2000MS   Memory Limit: 65536K
    Total Submissions: 27820   Accepted: 11208

    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

     
    题意:A喜欢B,B喜欢C,则A喜欢C,求被所有人喜欢的人的个数
    思路:将每个强连通分量缩点,然后求每个点的出度,如果有多个无出度的点则无解,否则答案就是出度为0的强连通分量内点的个数
     
    /*
    ID: LinKArftc
    PROG: 2186.cpp
    LANG: C++
    */
    
    #include <map>
    #include <set>
    #include <cmath>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <cstdio>
    #include <string>
    #include <utility>
    #include <cstdlib>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #define eps 1e-8
    #define randin srand((unsigned int)time(NULL))
    #define input freopen("input.txt","r",stdin)
    #define debug(s) cout << "s = " << s << endl;
    #define outstars cout << "*************" << endl;
    const double PI = acos(-1.0);
    const int inf = 0x3f3f3f3f;
    const int INF = 0x7fffffff;
    typedef long long ll;
    
    const int maxn = 10010;
    const int maxm = 50010;
    int n, m;
    
    struct Edge {
        int v, next;
    } edge[maxm];
    
    int head[maxn], tot;
    
    void init() {
        tot = 0;
        memset(head, -1, sizeof(head));
    }
    
    void addedge(int u, int v) {
        edge[tot].v = v;
        edge[tot].next = head[u];
        head[u] = tot ++;
    }
    
    int dfn[maxn], low[maxn], belong[maxn];//每个点属于哪个连通分量
    int scc;//连通分量总数,下标 1~scc
    int Time;
    int ins[maxn];
    stack <int> s;
    vector <int> vec[maxn];//记录每个连通分量内的点
    
    void tarjan(int u) {
        int v;
        low[u] = dfn[u] = ++ Time;
        s.push(u);
        ins[u] = true;
        for (int i = head[u]; i + 1; i = edge[i].next) {
            v = edge[i].v;
            if (!dfn[v]) {
                tarjan(v);
                low[u] = min(low[u], low[v]);
            } else if (ins[v]) low[u] = min(low[u], dfn[v]);//写出low[u] = min(low[u], low[v]);也可以
        }
        if (low[u] == dfn[u]) {
            scc ++;
            do {
                v = s.top();
                s.pop();
                ins[v] = false;
                belong[v] = scc;
                vec[scc].push_back(v);
            } while (u != v);
        }
    }
    
    int outdeg[maxn];
    
    int main() {
        //input;
        while (~scanf("%d %d", &n, &m)) {
            init();
            int u, v;
            for (int i = 1; i <= m; i ++) {
                scanf("%d %d", &u, &v);
                addedge(u, v);
            }
            while (!s.empty()) s.pop();
            for (int i = 1; i <= maxn; i ++) vec[i].clear();
            memset(dfn, 0, sizeof(dfn));
            memset(ins, 0, sizeof(ins));
            Time = 0; scc = 0;
            for (int i = 1; i <= n; i ++) {
                if (!dfn[i]) tarjan(i);
            }
            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].v;
                    if (belong[u] == belong[v]) continue;
                    outdeg[belong[u]] ++;
                }
            }
            int ans = 0;
            bool has = false;
            bool flag = false;
            int ii;
            for (int i = 1; i <= scc; i ++) {
                if (outdeg[i] == 0) {
                    ii = i;
                    if (has) {
                        flag = false;
                        break;
                    } else {
                        has = true;
                        flag = true;
                    }
                }
            }
            if (flag) printf("%d
    ", vec[ii].size());
            else printf("0
    ");
        }
        return 0;
    }
  • 相关阅读:
    [51单片机] TFT2.4彩屏1 [文字显示 画矩形]
    [51单片机] 中断1-中断整体介绍
    [汇编] 从键盘输入一个一位数字,然后响铃n声
    [汇编] 比较2个字符串是否相等
    [汇编] 将字符串里的一个'&'字符换成空格
    [汇编] 2数相加极简单版
    mysql的IFNULL函数
    mysql 中 unix_timestamp和from_unixtime函数
    Excel实现二级菜单联动
    Hibernate中@Embedded和@Embeddable注解
  • 原文地址:https://www.cnblogs.com/LinKArftc/p/4905916.html
Copyright © 2020-2023  润新知