zoukankan      html  css  js  c++  java
  • BZOJ 1051 [HAOI2006]受欢迎的牛

    1051: [HAOI2006]受欢迎的牛

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2909  Solved: 1532
    [Submit][Status][Discuss]

    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

    题解:抽象成有向图,缩点后一个点能被所有点访问到的充要条件是出度为一且唯一(呵呵。。。)。。。输出这个大点的数量就行。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<queue>
     6 #include<cstring>
     7 #define PAU putchar(' ')
     8 #define ENT putchar('
    ')
     9 using namespace std;
    10 const int maxn=100000+10,maxm=500000+10;
    11 int low[maxn],dfn[maxn],s[maxn],beg[maxn],top,scc,cz,indeg[10001],outdeg[10001];bool ins[maxn];
    12 struct ted{int x,y;ted*nxt;}adj[maxm],*fch[maxn],*ms=adj;
    13 void add(int x,int y){*ms=(ted){x,y,fch[x]};fch[x]=ms++;return;}
    14 void tarjan(int u){
    15     low[u]=dfn[u]=++cz;ins[u]=true;s[++top]=u;
    16     for(ted*e=fch[u];e;e=e->nxt){
    17         int v=e->y;if(!dfn[v])tarjan(v),low[u]=min(low[u],low[v]);
    18         else if(ins[v])low[u]=min(low[u],dfn[v]);
    19     }if(low[u]==dfn[u]){
    20         scc++;int t=-1;while(t!=u)beg[t=s[top--]]=scc,ins[t]=false;
    21     }return;
    22 }
    23 inline int read(){
    24     int x=0,sig=1;char ch=getchar();
    25     while(!isdigit(ch)){if(ch=='-')sig=-1;ch=getchar();}
    26     while(isdigit(ch))x=10*x+ch-'0',ch=getchar();
    27     return x*=sig;
    28 }
    29 inline void write(int x){
    30     if(x==0){putchar('0');return;}if(x<0)putchar('-'),x=-x;
    31     int len=0,buf[15];while(x)buf[len++]=x%10,x/=10;
    32     for(int i=len-1;i>=0;i--)putchar(buf[i]+'0');return;
    33 }
    34 void count_edge(){
    35     for(ted*e=adj;e!=ms;e++){
    36         int x=e->x,v=e->y;
    37         if(beg[x]!=beg[v])outdeg[beg[x]]++,indeg[beg[v]]++;
    38     }return;
    39 }
    40 int n,m;
    41 void init(){
    42     n=read();m=read();int x,y;
    43     for(int i=1;i<=m;i++)x=read(),y=read(),add(x,y);
    44     for(int i=1;i<=n;i++)if(dfn[i]==0)tarjan(i);
    45     count_edge();
    46     int s=0,st;
    47     for(int i=1;i<=scc;i++)if(!outdeg[i])s++,st=i;
    48     if(s==0||s>=2)puts("0");
    49     else{
    50         int sum=0;
    51         for(int i=1;i<=n;i++)if(beg[i]==st)sum++;
    52         write(sum);
    53     }
    54     return;
    55 }
    56 void work(){
    57     return;
    58 }
    59 void print(){
    60     return;
    61 }
    62 int main(){init();work();print();return 0;}
  • 相关阅读:
    Android使用SharedPreferences
    Flex程序基本结构顺序结构程序设计
    FLEX程序设计函数
    FLEX程序设计XML(2)
    FLEX程序设计事件和事件机制鼠标事件
    FLEX字符串
    FLEX程序基本结构循环结构程序设计
    Enum 作为一个数据源绑定(收藏)
    FLEX程序设计数字处理
    flex程序设计面向对象基础
  • 原文地址:https://www.cnblogs.com/chxer/p/4732089.html
Copyright © 2011-2022 走看看