zoukankan      html  css  js  c++  java
  • BZOJ 1051 受欢迎的牛

    Description

    每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。

    Input

    第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)

    Output

    一个数,即有多少头牛被所有的牛认为是受欢迎的。

    Sample Input

    3 3
    1 2
    2 1
    2 3

    Sample Output

    1

    HINT

    100%的数据N<=10000,M<=50000

    Source

    很明显,tarjan缩点+topsort,然后bitset大法好。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<bitset>
     5 #include<queue>
     6 #include<stack>
     7 #include<cstdlib>
     8 using namespace std;
     9 
    10 #define maxn 10010
    11 #define maxm 60010
    12 int n,m,cnt,tot,dfn[maxn],low[maxn],id[maxn],d[maxn];
    13 int side[maxn],toit[maxm],next[maxm];
    14 int nside[maxn],ntoit[maxm],nnext[maxm];
    15 stack <int> S; bitset <maxn> bit[maxn]; bool vis[maxn];
    16 
    17 inline void add(int a,int b) { next[++cnt] = side[a]; side[a] = cnt; toit[cnt] = b; }
    18 
    19 inline void ins(int a,int b)
    20 {
    21     nnext[++cnt] = nside[a]; ++d[b];
    22     nside[a] = cnt; ntoit[cnt] = b;
    23 }
    24 
    25 inline void dfs(int now)
    26 {
    27     S.push(now); dfn[now] = low[now] = ++cnt;
    28     for (int i = side[now];i;i = next[i])
    29         if (!vis[toit[i]])
    30         {
    31             if (!dfn[toit[i]]) dfs(toit[i]);
    32             low[now] = min(low[toit[i]],low[now]);
    33         }
    34     if (dfn[now] == low[now])
    35     {
    36         ++tot;
    37         while (S.top() != now) vis[S.top()] = true,id[S.top()] = tot,S.pop();
    38         vis[S.top()] = true,id[S.top()] = tot,S.pop();
    39     }
    40 }
    41 
    42 inline void rebuild()
    43 {
    44     cnt = 0;
    45     for (int i = 1;i <= n;++i)
    46     {
    47         bit[id[i]].set(i-1);
    48         for (int j = side[i];j;j = next[j])
    49             if (id[i] != id[toit[j]]) ins(id[i],id[toit[j]]);
    50     }
    51 }
    52 
    53 inline void topsort()
    54 {
    55     queue <int> team;
    56     for (int i = 1;i <= tot;++i) if (!d[i]) team.push(i);
    57     while (!team.empty())
    58     {
    59         int now = team.front(); team.pop();
    60         for (int i = nside[now];i;i = nnext[i])
    61         {
    62             bit[ntoit[i]] |= bit[now];
    63             if (!--d[ntoit[i]]) team.push(ntoit[i]);
    64         }
    65     }
    66     int ans = 0;
    67     for (int i = 1;i <= n;++i) if (bit[id[i]].count() == n) ++ans;
    68     printf("%d",ans);
    69 }
    70 
    71 int main()
    72 {
    73     freopen("1051.in","r",stdin);
    74     freopen("1051.out","w",stdout);
    75     scanf("%d %d",&n,&m);
    76     for (int i = 1;i <= n;++i) add(i,i);
    77     while (m--) { int a,b; scanf("%d %d",&a,&b); add(a,b); }
    78     cnt = 0;
    79     for (int i = 1;i <= n;++i) if (!dfn[i]) dfs(i);
    80     rebuild();
    81     topsort();
    82     fclose(stdin); fclose(stdout);
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    085 Maximal Rectangle 最大矩形
    084 Largest Rectangle in Histogram 柱状图中最大的矩形
    083 Remove Duplicates from Sorted List 有序链表中删除重复的结点
    082 Remove Duplicates from Sorted List II 有序的链表删除重复的结点 II
    081 Search in Rotated Sorted Array II 搜索旋转排序数组 ||
    080 Remove Duplicates from Sorted Array II 从排序阵列中删除重复 II
    079 Word Search 单词搜索
    078 Subsets 子集
    bzoj2326: [HNOI2011]数学作业
    bzoj2152: 聪聪可可
  • 原文地址:https://www.cnblogs.com/mmlz/p/4280516.html
Copyright © 2011-2022 走看看