• [BZOJ1051][HAOI2006] 受欢迎的牛 tarjan求联通分量


    1051: [HAOI2006]受欢迎的牛

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 5687  Solved: 3016
    [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
     
     
     
     
    我们可以对于这个图进行tarjan求强联通分量并缩点,对于缩点后的每一个点,若他是唯一出度为0的点,就说明他之中的所有牛被众人%膜拜%,否则无解。
    代码:
     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #include<cmath>
     6 #include<cstdlib>
     7 using namespace std;
     8 struct data
     9 {
    10     int next,to;
    11 }e[100001],e1[100001];
    12 int n,m;
    13 int head[50005],cnt,head1[50005],cnt1;
    14 int dfn[50005],low[50005];
    15 bool vis[50005],inq[50005];
    16 int q[50005],top;
    17 int tim;
    18 int scc;
    19 int size[50005];
    20 int belong[50005];
    21 void add(int u,int v){e[cnt].next=head[u];e[cnt].to=v;head[u]=cnt;cnt++;}
    22 void add1(int u,int v){e1[cnt1].next=head1[u];e1[cnt1].to=v;head1[u]=cnt1;cnt1++;}
    23 void dfs(int now)
    24 {
    25     dfn[now]=low[now]=++tim;
    26     vis[now]=inq[now]=1;
    27     q[++top]=now;
    28     for(int i=head[now];i>=0;i=e[i].next)
    29     {
    30         int to=e[i].to;
    31         if(!vis[to])
    32         {
    33             dfs(to);
    34             low[now]=min(low[to],low[now]);
    35         }
    36         else if(inq[to]) low[now]=min(low[now],dfn[to]);
    37     }
    38     if(low[now]==dfn[now])
    39     {
    40         scc++;
    41         int c=0;
    42         while(c!=now)
    43         {
    44             c=q[top--];
    45             inq[c]=0;
    46             belong[c]=scc;
    47             size[scc]++;
    48         }
    49     }
    50 }
    51 void rebuild()
    52 {
    53     memset(head1,-1,sizeof(head1));
    54     for(int i=1;i<=n;i++)
    55         for(int j=head[i];j>=0;j=e[j].next)
    56         {
    57             int to=e[j].to;
    58             if(belong[i]!=belong[to]) add1(belong[i],belong[to]);
    59         }
    60 }
    61 void tarjan()
    62 {
    63     for(int i=1;i<=n;i++) if(!vis[i]) dfs(i);
    64     rebuild();
    65 }
    66 void work()
    67 {
    68     int ans=0;
    69     for(int i=1;i<=scc;i++)
    70     {
    71         if(head1[i]==-1)
    72         {
    73             if(ans){ans=0;cout<<ans;return ;}
    74             else{ans=size[i];}
    75         }
    76     }
    77     cout<<ans;
    78 }
    79 int main()
    80 {
    81     memset(head,-1,sizeof(head));
    82     scanf("%d%d",&n,&m);
    83     for(int i=1;i<=m;i++)
    84     {
    85         int u,v;
    86         scanf("%d%d",&u,&v);
    87         add(u,v);
    88     }
    89     tarjan();
    90     work();
    91 }
    92 
    View Code
    O(∩_∩)O~ (*^__^*) 嘻嘻…… O(∩_∩)O哈哈~
  • 相关阅读:
    正则表达式解决身份证号码和手机号
    redis:集群配置
    linux:NFS
    xshell提示必须安装最新的更新
    linux:ssh远程调用tomcat脚本时候出错
    linux:scp从入门到刚入门
    linux:SSH最简单教程
    nginx;keepalived配置出现主主的解决方法(脑裂问题)
    (4)事件处理——(4)网页上的多个脚本(Multiple scripts on one page)
    [php]应用控制器(一)
  • 原文地址:https://www.cnblogs.com/wls001/p/7209571.html
Copyright © 2020-2023  润新知