zoukankan      html  css  js  c++  java
  • 【模板】Tarjan缩点,强连通分量 洛谷P2341 [HAOI2006]受欢迎的牛 [2017年6月计划 强连通分量01]

    P2341 [HAOI2006]受欢迎的牛

    题目描述

    每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶

    牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜

    欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你

    算出有多少头奶牛可以当明星。

    输入输出格式

    输入格式:

     第一行:两个用空格分开的整数:N和M

     第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B

    输出格式:

     第一行:单独一个整数,表示明星奶牛的数量

    输入输出样例

    输入样例#1:
    3 3
    1 2
    2 1
    2 3
    输出样例#1:
    1

    说明

    只有 3 号奶牛可以做明星

    【数据范围】

    10%的数据N<=20, M<=50

    30%的数据N<=1000,M<=20000

    70%的数据N<=5000,M<=50000

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

    模板题,出度为零的点有且仅有一个才有解,解即为该点内的点数。

     1 #include <bits/stdc++.h>
     2 const int INF = 0x3f3f3f3f;
     3 const int MAXN = 10000 + 10;
     4 const int MAXM = 50000 + 10; 
     5 inline int read(int &x){
     6     x = 0;char ch = getchar();char c = ch;
     7     while(ch > '9' || ch < '0')c = ch, ch = getchar();
     8     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0',ch = getchar();
     9     if(c == '-') x = -x;
    10 }
    11 inline int min(int a,int b){return a > b? b : a;}
    12 int n,m,tmp1,tmp2,cnt,cnt2,head[MAXN],head2[MAXN];
    13 int dfn[MAXN],low[MAXN], group, num[MAXN],belong[MAXN], t, stack[MAXN], top;
    14 bool b[MAXN],bb[MAXN];
    15 struct Edge{int u,v,next;}edge[MAXM],edge2[MAXM];
    16 void insert(int a,int b){edge[++cnt] = Edge{a, b, head[a]};head[a] = cnt;}
    17 void insert2(int a,int b){edge2[++cnt2] = Edge{a, b, head2[a]};head2[a] = cnt2;}
    18 void dfs(int u){
    19     int now = -1;
    20     b[u] = true;bb[u] = true;
    21     dfn[u] = low[u] = ++t;
    22     stack[++top] = u;
    23     for(int pos = head[u];pos;pos = edge[pos].next){
    24         int v = edge[pos].v;
    25         if(!b[v]){
    26             dfs(v);
    27             if(low[u] > low[v])low[u] = low[v];
    28         }
    29         else if(bb[v] && low[u] > dfn[v]){
    30             low[u] = dfn[v];
    31         }
    32     }
    33     if(low[u] == dfn[u]){
    34         group ++;
    35         while(now != u){
    36             now = stack[top --];
    37             bb[now] = false;
    38             belong[now] = group;
    39             num[group] ++;
    40         }
    41     }
    42 }
    43 inline void rebuild(){
    44     for(int u = 1;u <= n;u ++){
    45         for(int pos = head[u];pos;pos = edge[pos].next){
    46             int v = edge[pos].v;
    47             if(belong[u] != belong[v]){
    48                 insert2(belong[u], belong[v]);
    49             }
    50         }
    51     } 
    52 } 
    53 inline void tarjan(){
    54     for(int i = 1;i <= n;i ++)if(!b[i])dfs(i);
    55     rebuild();
    56 }
    57 int ans;
    58 int main(){
    59     read(n);read(m);
    60     for(int i = 1;i <= m;i ++){
    61         read(tmp1);read(tmp2);insert(tmp1, tmp2);
    62     }
    63     tarjan();
    64     for(int i = 1;i <= group;i ++){
    65         if(!head2[i]){
    66             if(ans) ans = 0;break;
    67             else ans = num[i];
    68         }
    69     }
    70     printf("%d", ans);
    71     return 0;
    72 }
  • 相关阅读:
    爬虫-selenium模块
    动画《区块链100问》第4集:第一个比特币诞生啦!
    动画《区块链100问》第5集:谁是中本聪?
    动画《区块链100问》第6集:密码朋克是什么?
    动画《区块链100问》第7集:比特币是怎么发行的?
    动画《区块链100问》第8集:披萨居然卖到3亿元?
    动画《区块链100问》第9集:中本聪的继任者是谁?
    动画《区块链100问》第10集:早期比特币还能白送!
    《区块链100问》第11集:比特币为什么还没挖完?
    《区块链100问》第12集:比特币如何实现总量恒定?
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/6964136.html
Copyright © 2011-2022 走看看