zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    iOS的图片:解码(CPU)与内存(缓存)
    iOS离屏渲染的解释:渲染与cpu、gpu
    渲染、render与绘制
    算法沉思:算法的构成
    待阅备份
    iOS进阶之页面性能优化
    iOS--性能优化--保持界面流畅
    iOS开发中的Markdown渲染
    OS开发小记:iOS富文本框架DTCoreText在UITableView上的使用
    iOS UI的几种模式
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9039668.html
Copyright © 2011-2022 走看看