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
  • 相关阅读:
    对象流(序列化,反序列化)
    随机存取文件流(双性流)
    网络编程
    ByteArrayOutputStream小测试
    Java基础
    IO流实现GBK写入文件然后转换UTF-8
    IO流实现简单的文件的剪切
    递归
    ZKDQ--问题整理
    postman测试上传文件接口
  • 原文地址:https://www.cnblogs.com/mmlz/p/4280516.html
Copyright © 2011-2022 走看看