• p2341&bzoj1051 受欢迎的牛


    传送门(洛谷)

    传送门(bzoj)

    题目

    每一头牛的愿望就是变成一头最受欢迎的牛。现在有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缩点同时计算一个环内的点的数量(这个时候就把自己算进去了),重新建图之后我们经过感性思考不难想出如果要让所有牛都喜欢最基本的条件就是出度为零,因为如果有出度就代表这个点指向了别的点,而在一个有向无环图中这就代表了一定有点不指向出度非零的点,但如果有大于一个出度为零的点就代表图是不连通的,所以直接输出零,而如果只有一个出度为零的点,就输出这个点所代表的环所含点的个数

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<queue>
    #include<ctime>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    int dfn[110000],low[110000],star[110000],cnt,sum,belong[110000];
    int num[110000],isr[110000];
    vector<int>v[110000];
    stack<int>a;
    stack<int>b;
    queue<int>q;
    void tarjan(int x){
          low[x]=dfn[x]=++cnt;
          a.push(x);
          isr[x]=1;
          int i,j,k;
          for(i=0;i<v[x].size();i++)
             if(!dfn[v[x][i]]){
                 tarjan(v[x][i]);
                 low[x]=min(low[x],low[v[x][i]]);
             }else if(isr[x]){
                 low[x]=min(low[x],dfn[v[x][i]]);
             }
          if(dfn[x]==low[x]){
              int tot=0;
              sum++;
              while(1){
                  int u=a.top();
                  belong[u]=sum;
                  b.push(u);
                  tot++;
                  a.pop();
                  isr[u]=0;
                  if(u==x)break;
              }
              while(!b.empty()){
                  star[sum]=tot;
                  b.pop();
              }
          }
    }
    int main()
    {     int n,m,i,j,k,x,y;
          cin>>n>>m;
          for(i=1;i<=m;i++){
              cin>>x>>y;
              v[x].push_back(y);
          }
          for(i=1;i<=n;i++)
             if(!dfn[i])tarjan(i);
          for(i=1;i<=n;i++)
             for(j=0;j<v[i].size();j++)
                if(belong[v[i][j]]!=belong[i]){
                  num[belong[i]]++;
                }
          int wh,tot=0;
          for(i=1;i<=sum;i++)
             if(!num[i]){
                 tot++;
                 wh=i;
             }
          if(tot!=1){
              cout<<0<<endl;
              return 0;
          }
          cout<<star[wh]<<endl;
          return 0;
    }

  • 相关阅读:
    什么是Shader
    [Tip: Interface Implementation]
    Focus在某一领域的软件开发 + 在那一领域无限扩展视野
    [Tip: VS]Several IDE Tips and Tricks
    [Tip C# collection]List<Employee> or EmployeeList?
    [Tip Regular expression]Test Regular Expressions With The Regulator
    VS2005设计智能客户端(轉)
    第1章 本书会讨论什么内容
    [导入]关于Sprite.Draw2D
    C#面試(轉)
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9039668.html
Copyright © 2020-2023  润新知