• bzoj 1051 受欢迎的牛


    题目大意:

    现在有N头牛,给一个 A B 表示牛A认为牛B受欢迎

    这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少牛被所有的牛认为是受欢迎的

    思路:

    先用tarjan把每个强连通分量缩点

    然后脑补一下

    可以发现如果有大于一个连通分量出度为零,则不可能有解  因为这几个出度为零部分的牛互相不能认为对方受欢迎

    所以只有当所有强连通分量只有一个出度为零的时候 解为那个连通分量的大小

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<cmath>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<set>
     8 #include<map>
     9 #include<vector>
    10 #include<stack>
    11 #include<queue>
    12 #define ll long long
    13 #define inf 2147383611
    14 #define MAXN 100100
    15 #define MOD 5050
    16 using namespace std;
    17 inline int read()
    18 {
    19     int x=0,f=1;
    20     char ch;ch=getchar();
    21     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
    22     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
    23     return x*f;
    24 }
    25 int n,m,next[MAXN*2],first[MAXN],to[MAXN*2],cnt;
    26 int Next[MAXN*2],First[MAXN],To[MAXN*2],otd[MAXN];
    27 int scc,dfn[MAXN],low[MAXN],bl[MAXN],stp,num[MAXN];
    28 bool vis[MAXN];
    29 int st[MAXN],top;
    30 void add(int u,int v) {next[++cnt]=first[u],first[u]=cnt,to[cnt]=v;}
    31 void ADD(int u,int v) {Next[++cnt]=First[u],First[u]=cnt,To[cnt]=v;otd[u]++;}
    32 void tarjan(int x)
    33 {
    34     low[x]=dfn[x]=++stp,st[++top]=x,vis[x]=1;
    35     for(int i=first[x];i;i=next[i])
    36     {
    37         if(!dfn[to[i]])
    38         {
    39             tarjan(to[i]);low[x]=min(low[x],low[to[i]]);
    40         }
    41         else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
    42     }
    43     if(low[x]==dfn[x])
    44     {
    45         scc++;
    46         while(st[top+1]!=x) bl[st[top]]=scc,num[scc]++,vis[st[top]]=0,top--;
    47     }
    48 }
    49 void rebuild()
    50 {
    51     cnt=0;
    52     for(int i=1;i<=n;i++)
    53         for(int j=first[i];j;j=next[j])
    54             if(bl[i]!=bl[to[j]]) ADD(bl[i],bl[to[i]]);
    55 }
    56 int main()
    57 {
    58     n=read(),m=read();
    59     int a,b;
    60     while(m--)
    61     {
    62         a=read(),b=read();
    63         add(a,b);
    64     }
    65     for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i);
    66     rebuild();
    67     cnt=0;int k;
    68     for(int i=1;i<=scc;i++) if(!otd[i]) {cnt++;k=i;}
    69     if(cnt==1) printf("%d",num[k]);
    70     else printf("0");
    71 }
    View Code

     

  • 相关阅读:
    51 nod 1181 质数中的质数(质数筛法)
    Just oj 2018 C语言程序设计竞赛(高级组)F:Star(结构体排序+最小生成树)
    欧拉函数+费马小定理拓展
    ZOJ 3785 What day is that day?(数论:费马小定理)
    Just oj 2018 C语言程序设计竞赛(高级组)H: CBT?
    树链剖分(入门学习)
    bitset用法
    链式前向星
    Nearest Common Ancestors(LCA板子)
    LCA(最近公共祖先)
  • 原文地址:https://www.cnblogs.com/yyc-jack-0920/p/7756042.html
Copyright © 2020-2023  润新知