• 洛谷 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

     

    分析

     

    • 首先,刚开始我理解错了
    • 以为只有一个明星
    • 但是其实明星也是可以喜欢别人的
    • 所以真的正解
    • 是求两两强连通分量的出度为0的点的个数
    • 因为在同一强联通分量里面,每一头牛都是在里面的明星
    • 要是里面有一头牛与另一个强连通分量里随便一个牛相连
    • 那么两个强连通分量就相连
    • 统计答案即可

     

    代码

     1 #include<iostream>
     2 #include<cstring>
     3 using namespace std;
     4 int vis[10001],dfn[10001],low[10001],stack[10001],color[10001],top,col,num,sum[10001],d[10001];
     5 int out[10001];
     6 struct sb
     7 {
     8     int to,nx;
     9 }g[100010];
    10 int cnt,list[100010];
    11 void add(int x,int y)
    12 {
    13     g[++cnt].to=y; g[cnt].nx=list[x]; list[x]=cnt;
    14 }
    15 void tarjan(int x)
    16 {
    17     dfn[x]=low[x]=++num;
    18     vis[x]=1;
    19     stack[++top]=x;
    20     for (int i=list[x];i;i=g[i].nx)
    21     {
    22         int y=g[i].to;
    23         if (!dfn[y])
    24         {
    25             tarjan(y);
    26             low[x]=min(low[x],low[y]);
    27         }
    28         else if (vis[y]) low[x]=min(low[x],dfn[y]);
    29     }
    30     if (dfn[x]==low[x])
    31     {
    32         ++col;
    33         while (stack[top+1]!=x)
    34         {
    35             ++sum[col];
    36             color[stack[top]]=col;
    37             vis[stack[top--]]=0;
    38         }
    39     }
    40 }
    41 int main ()
    42 {
    43     int n,m;
    44     cin>>n>>m;
    45     for (int i=1,x,y;i<=m;i++)
    46     {
    47         cin>>x>>y;
    48         add(x,y);
    49     }
    50     for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i);
    51     for (int i=1;i<=n;i++)
    52       for (int j=list[i];j;j=g[j].nx)
    53       {
    54            int y=g[j].to;
    55            if (color[i]!=color[y]) d[color[i]]++;
    56       }
    57     int ans=0,k=0;
    58     for (int i=1;i<=col;i++)
    59       if (!d[i]) ans=sum[i],k++;
    60     if (k==1) cout<<ans;
    61     else cout<<0;
    62 }

     

  • 相关阅读:
    java中分页对象类
    java日期处理类DateUtil
    java日期处理类DateUtil
    Java Socket编程
    MySQL中TIMESTAMPDIFF和TIMESTAMPADD函数的用法
    java中用SAX方式解析xml文件
    First Demo
    软件测试面试/笔试题题库(知识的搬运工,不谢!)
    2017年 6月29 开始博客园之旅--愿自己变得更强大!
    DUIEngine使用Visual Studio 2010编译Debug_Dll版有关Error MSB3073错误解决方案
  • 原文地址:https://www.cnblogs.com/zjzjzj/p/11334369.html
Copyright © 2020-2023  润新知