• BZOJ1051 [HAOI2006] 受欢迎的牛


    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=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

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

    复习Tarjan模版,Tarjan后缩点,若有且只有一个出度为0的强联通分量则输出其大小,否则无解

    因为缩点后的图是没有双向边的(如果有那就是一个强联通分量了)

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #include <stack>
     6 #define rep(i,l,r) for(int i=l; i<=r; i++)
     7 #define clr(x,y) memset(x,y,sizeof(x))
     8 #define travel(x) for(int i=last[x]; i; i=edge[i].pre)
     9 using namespace std;
    10 const int INF = 0x3f3f3f3f;
    11 const int maxn = 10010;
    12 struct Edge{
    13     int pre,to;
    14 }edge[50010];
    15 int n,m,x,y,tot=0,ans,scc=0,dfsclock=0,last[maxn],dfn[maxn],low[maxn],belong[maxn],cnt[maxn];
    16 bool isin[maxn],oud[maxn];
    17 stack <int> s;
    18 inline int read(){
    19     int ans = 0, f = 1;
    20     char c = getchar();
    21     while (!isdigit(c)){
    22         if (c == '-') f = -1;
    23         c = getchar();
    24     }
    25     while (isdigit(c)){
    26         ans = ans * 10 + c - '0';
    27         c = getchar();
    28     }
    29     return ans * f;
    30 }
    31 inline void addedge(int x,int y){
    32     edge[++tot].pre = last[x];
    33     edge[tot].to = y;
    34     last[x] = tot;
    35 }
    36 void tarjan(int x){
    37     dfn[x] = low[x] = ++dfsclock;
    38     isin[x] = 1; s.push(x);
    39     travel(x){
    40         if (!dfn[edge[i].to]){
    41             tarjan(edge[i].to);
    42             low[x] = min(low[x],low[edge[i].to]);
    43         }
    44         else if (isin[edge[i].to]) low[x] = min(low[x],dfn[edge[i].to]);
    45     }
    46     if (low[x] == dfn[x]){
    47         scc++;
    48         while (s.top() != x){
    49             isin[s.top()] = 0;
    50             belong[s.top()] = scc;
    51             s.pop();
    52             cnt[scc]++;
    53         }
    54         isin[x] = 0; belong[x] = scc; s.pop(); cnt[scc]++;
    55     }
    56 }
    57 int main(){
    58     n = read(); m = read();
    59     rep(i,1,m) x = read(), y = read(), addedge(x,y);
    60     clr(dfn,0); clr(cnt,0);
    61     rep(i,1,n) if (!dfn[i]) tarjan(i);
    62     clr(oud,0);
    63     rep(now,1,n) travel(now) if (belong[now] != belong[edge[i].to]) oud[belong[now]] = 1;
    64     ans = 0;
    65     rep(i,1,scc) if (!oud[i]){
    66         if (ans){ans = 0; break;}
    67         ans = cnt[i];
    68     }
    69     printf("%d
    ",ans);
    70     return 0;
    71 }
    View Code
  • 相关阅读:
    Shell编程-02-Shell变量
    Linux 下强大的查找命令find
    DevOps 学院
    史上最详细、最全面的Hadoop环境搭建
    Linux 中10个命令链接操作符,帮助新手快速入门运维!
    25个Linux性能监控工具
    一文详解 Linux系统常用监控工具
    ansible 安装指南
    Tomcat管理页面
    Tomcat基础知识
  • 原文地址:https://www.cnblogs.com/jimzeng/p/bzoj1051.html
Copyright © 2020-2023  润新知