zoukankan      html  css  js  c++  java
  • #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<bits/stdc++.h>
      2 #pragma comment(linker, "/STACK:102400000,102400000") //手动扩栈跑的快~~
      3 #define N 10050
      4 using namespace std;
      5 struct EDGE
      6 {
      7     int next,to;
      8 }edge[N*20];
      9 int head[20*N],dfn[N],low[N];
     10 int du[N],id[N],all[N];
     11 bool insta[N];
     12 int cnt,tot,gg,n,m;
     13 stack<int>s;
     14 void add(int x,int y)
     15 {
     16     cnt++;
     17     edge[cnt].to=y;
     18     edge[cnt].next=head[x];
     19     head[x]=cnt;
     20 }
     21 void in(int &read)
     22 {
     23     int x=0,f=1;
     24     char ch;
     25     for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
     26     if(ch=='-')
     27     {
     28         f=-1;
     29         ch=getchar();
     30     }
     31     while(ch>='0'&&ch<='9')
     32     {
     33         x=(x<<3)+(x<<1)+ch-'0';
     34         ch=getchar();
     35     }
     36     read=x*f;
     37     }
     38 void tarjan(int x)//targan模版 
     39 {
     40     dfn[x]=low[x]=++tot;
     41     s.push(x);insta[x]=true;
     42     for(int i=head[x];i;i=edge[i].next)
     43     {
     44         int u=edge[i].to;
     45         if(!dfn[u])
     46         {
     47             tarjan(u);
     48             low[x]=min(low[x],low[u]);
     49         }
     50         else if(insta[u])low[x]=min(low[x],dfn[u]);
     51     }
     52     int k;
     53     if(low[x]==dfn[x])
     54     {
     55         ++gg;
     56         while(x!=k)
     57         {
     58             k=s.top();s.pop();
     59             insta[k]=false;
     60             id[k]=gg;all[gg]++;
     61         }
     62     }
     63 }
     64 int main()
     65 {
     66     in(n);
     67     in(m);
     68     int a,b;
     69     for(int i=1;i<=m;i++)
     70     {
     71         in(a);
     72         in(b);
     73         add(a,b);
     74     }
     75     for(int i=1;i<=n;i++)
     76     {
     77         if(!dfn[i])
     78             tarjan(i);
     79     }
     80     for(int w=1;w<=n;w++)
     81     {
     82         for(int i=head[w];i;i=edge[i].next)
     83         {
     84             int u=edge[i].to;
     85             if(id[w]!=id[u])
     86             {
     87                 du[id[w]]++;
     88             }
     89         }
     90     }
     91     int tt=0;
     92     for(int i=1;i<=gg;i++)
     93     {
     94         if(!du[i])
     95         {
     96             if(tt)
     97             {
     98                 puts("0");
     99                 return 0;
    100             }
    101             tt=i;
    102         }
    103     }
    104     printf("%d",all[tt]);
    105     return 0;
    106 }
    View Code
  • 相关阅读:
    Eclipse常见配置及常用插件
    杂记
    表单双引号问题
    兼容ie的jquery ajax文件上传
    Markdown 學習
    jstl c标签
    java 在接口里函数不能重载?
    【转】Eclipse里项目名有红叉,但是展开后里面又没有红叉叉
    Android性能优化之一:ViewStub
    Merge用法
  • 原文地址:https://www.cnblogs.com/ssf-lrk/p/11225444.html
Copyright © 2011-2022 走看看