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

    1051: [HAOI2006]受欢迎的牛

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2685  Solved: 1407
    [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
     
    970558 ws_fqk 1051 Accepted 3712 kb 96 ms C++/Edit 2371 B 2015-05-12 15:31:34
    970484 ws_fqk 1051 Wrong_Answer 3468 kb ms C++/Edit 2374 B 2015-05-12 14:48:33
    970467 ws_fqk 1051 Runtime_Error 3476 kb ms C++/Edit 2365 B 2015-05-12 14:35:52

    第一遍不知道为何RE……第二遍变量名打错WA,找了半个多小时(555555),奇怪的是还得了30分。。。发现后就A掉了。

    分析:

    对于某连通块内的牛,是相互喜欢的,所以可以tarjan找出这样的连通块然后缩成一个点。再重新构图。

    然后找出度为0的点,即为答案。否则无解,若有两个及以上出度为0的点也无解(因为出度为0的点之间不能相互喜欢)。

    第一次写tarjan……

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    int head[50001],next[50001],list[50001],head0[50001],next0[50001],list0[50001],dfn[50001],low[50001],stack[50001],belong[50001],num[50001];
    int n,m,tot,tot0,top,cnt,sum,ans,a,b;
    bool inset[50001];
    void insert(int a,int b)
    {
         tot++;
         next[tot]=head[a];
         head[a]=tot;
         list[tot]=b;
    }
    void insert0(int a,int b)
    {
         next0[++tot0]=head0[a];
         head0[a]=tot0;
         list0[tot0]=b;
    }
    void dfs(int x)
    {
         dfn[x]=low[x]=++sum;
         stack[++top]=x;
         inset[x]=1;
         int y=head[x];
         while (y!=0)
         {
               if (!dfn[list[y]])
               {
                               dfs(list[y]);
                               low[x]=min(low[x],low[list[y]]);
               }
               if (inset[list[y]]&&dfn[list[y]]<low[x]) low[x]=dfn[list[y]];
               y=next[y];
         }
         y=-1;
         if (dfn[x]==low[x])
         {
                            cnt++;
                            while (y!=x)
                            {
                                  y=stack[top--];
                                  inset[y]=0;
                                  belong[y]=cnt;
                                  num[cnt]++;
                            }
         }
    }
    void rebuild()
    {
         int y;
         for (int i=1;i<=n;i++)
         {
             y=head[i];
             while (y!=0)
             {
                   if (belong[i]!=belong[list[y]]) insert0(belong[i],belong[list[y]]);
                   y=next[y];
             }
         }
    }
    void tarjan()
    {
         for (int i=1;i<=n;i++) if (!dfn[i]) dfs(i);
    }
    int main()
    {
        tot=0; sum=0; top=0; cnt=0; tot0=0; ans=0;
        memset(dfn,0,sizeof(dfn));
        memset(low,0,sizeof(low));
        memset(inset,0,sizeof(inset));
        memset(belong,0,sizeof(belong));
        memset(num,0,sizeof(num));
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++)
        {
            scanf("%d%d",&a,&b);
            insert(a,b);
        }
        tarjan();
        rebuild();
        for (int i=1;i<=cnt;i++)
            if (!head0[i]) {if (ans) {ans=0; break;} else ans=num[i];}
        printf("%d
    ",ans);
        return 0;
    }                  
  • 相关阅读:
    GZIP压缩
    对象的constructor属性
    session会话复制
    第一篇博客 iframe自适应高度
    【NOI2012T4】迷失游乐园-环套树+树形DP+期望DP
    【NOI2012T4】迷失游乐园-环套树+树形DP+期望DP
    【HDU5072】Coprime-补集转化+容斥原理+质因数分解
    【HDU5072】Coprime-补集转化+容斥原理+质因数分解
    【NOI2011T1】兔农-矩阵快速幂+乘法逆元
    【NOI2011T1】兔农-矩阵快速幂+乘法逆元
  • 原文地址:https://www.cnblogs.com/ws-fqk/p/4497474.html
Copyright © 2011-2022 走看看