zoukankan      html  css  js  c++  java
  • 【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点

    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

     1A啦啦啦~ 新姿势tarjan算法(现在才学太弱啦!),tarjan算法求完强连通分量后进行缩点,然后查找出度为0的唯一的点(缩的点),为什么是唯一的,很简单,因为其他点都有出度,也就是其他所有点都连在一起指向该点,若不唯一,就误无解。
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <queue>
     5 #include <stack>
     6 #define N 10010
     7 #define M 50050
     8 using namespace std;
     9 struct data1{int p,next;}e[M];
    10 int ans,cnt,n,m,scc;
    11 int head[N],dfn[N],low[N],vis[N],inq[N],h[N],belong[N],ringsum[N];
    12 stack<int> q;
    13 void se(int x,int y){cnt++;e[cnt].next=head[x];head[x]=cnt;e[cnt].p=y;}
    14 void Tarjan(int x)
    15 {
    16     vis[x]=inq[x]=1;
    17     low[x]=dfn[x]=++cnt;;
    18     q.push(x);
    19     for (int i=head[x];i!=-1;i=e[i].next)
    20     {
    21         if (!vis[e[i].p])
    22         {
    23             Tarjan(e[i].p);
    24             low[x]=min(low[x],low[e[i].p]);
    25         }
    26         else if (inq[e[i].p])    low[x]=min(low[x],low[e[i].p]);
    27     }
    28     if (dfn[x]==low[x])
    29     {
    30         int now;
    31         scc++;
    32         while (now!=x)
    33         {
    34             now=q.top();q.pop();
    35             belong[now]=scc;
    36             inq[now]=0;
    37             ++ringsum[scc];
    38         }
    39     }
    40 }
    41 void part1_tarjan()
    42 {
    43     cnt=0;
    44     for (int i=1;i<=n;i++)
    45         if (!vis[i])
    46             Tarjan(i);
    47 }
    48 void part2_shr_point()
    49 {
    50     for (int i=1;i<=n;i++)
    51         for (int t=head[i];t!=-1;t=e[t].next)
    52             if (belong[i]!=belong[e[t].p])
    53                 h[belong[i]]=1;
    54 }
    55 void part3_doit()
    56 {
    57     for (int i=1;i<=scc;i++)
    58         if (!h[i])
    59         {
    60             if (ans)
    61             {
    62                 ans=0;
    63                 return;
    64             }
    65             else    ans=ringsum[i];
    66         }
    67 }
    68 int main()
    69 {
    70     memset(e,-1,sizeof(e));
    71     memset(head,-1,sizeof(head));
    72     scanf("%d%d",&n,&m);
    73     for (int i=1;i<=m;i++)
    74     {
    75         int x,y;
    76         scanf("%d%d",&x,&y);
    77         se(x,y);
    78     }
    79     part1_tarjan();
    80     part2_shr_point();
    81     part3_doit();
    82     printf("%d
    ",ans);
    83     return 0;
    84 }
    View Code
    —Anime Otaku Save The World.
  • 相关阅读:
    在mac上搭建python环境
    iOS开发-你真的会用SDWebImage?(转发)
    iOS tableview 优化总结
    Masonry 实现输入框随键盘位置改变
    sudo 权限问题
    nodejs save遇到的一个坑
    iOS app的webview注入JS遇到的坑
    HW18-广搜
    HW17-深搜
    HW16-动归2
  • 原文地址:https://www.cnblogs.com/DMoon/p/5251850.html
Copyright © 2011-2022 走看看