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;
    }

  • 相关阅读:
    ksframework的xlua版本
    unity摄像机脚本
    代码重构:用工厂+策略模式优化过多的if else代码块
    在Unity中创建攻击Slot系统
    Unity运用GPU代替CPU处理和计算简单测试
    程序员工具集
    Unity开发-你必须知道的优化建议
    unity向量计算
    ClassFoo-IT知识花园
    BZOJ 3446: [Usaco2014 Feb]Cow Decathlon( 状压dp )
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/9039668.html
Copyright © 2011-2022 走看看