zoukankan      html  css  js  c++  java
  • 【tarjan+缩点】BZOJ1051-受欢迎的牛

    【题意】

    每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。

    【思路】

    存在于首页的经典老题,之前POJ的那道题做过之后无压力1A水过。

    先用tarjan将所有联通分量进行缩点,缩点后考虑出度为0的点的个数:

    (1)个数大于1的时候,显然不存在受欢迎的牛!

    (2)个数等于0的时候,假设有一头牛X是受欢迎的,那么它必定有喜欢的牛Y,而它又收到牛Y的欢迎,说明存在环,不是DAG图,矛盾!

    (3)个数等于1的时候,用数学归纳法推一下,有这样一个结论:出度为0的那个点可以被其它所有点到达

    有了这样的结论,直接做就可以了XD

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<cstring>
     5 #include<vector>
     6 #include<stack>
     7 #include<cmath>
     8 #include<algorithm>
     9 const int MAXN=10000+500;
    10 const int MAXM=50000+500;
    11 using namespace std;
    12 int vis[MAXN],instack[MAXN];
    13 int u[MAXM],v[MAXM]; 
    14 int b[MAXN],sum[MAXN];
    15 int dfn[MAXN],low[MAXN];
    16 vector<int> E[MAXN];
    17 stack<int> S;
    18 int n,m;
    19 int cnt=-1,T=0;
    20  
    21 void tarjan(int u)
    22 {
    23     dfn[u]=low[u]=++T;
    24     vis[u]=1;
    25     S.push(u);
    26     instack[u]=1;
    27      
    28     for (int i=0;i<E[u].size();i++)
    29     {
    30         int son=E[u][i];
    31         if (!vis[son])
    32         {
    33             tarjan(son);
    34             low[u]=min(low[son],low[u]);
    35         }
    36         else
    37         if (vis[son] && instack[son])
    38             low[u]=min(dfn[son],low[u]);
    39     }
    40      
    41     if (dfn[u]==low[u])
    42     {
    43         cnt++;
    44         int x;
    45         do
    46         {
    47              x=S.top();
    48              S.pop();
    49              sum[cnt]++;
    50              b[x]=cnt;
    51              instack[x]=0;
    52         }while (x!=u);
    53     }
    54 } 
    55  
    56 void init()
    57 {
    58     memset(vis,0,sizeof(vis));
    59     memset(sum,0,sizeof(sum));
    60     memset(instack,0,sizeof(instack));
    61     scanf("%d%d",&n,&m);
    62     for (int i=0;i<m;i++)
    63     {
    64         scanf("%d%d",&u[i],&v[i]);
    65         E[u[i]].push_back(v[i]);
    66     }
    67 }
    68  
    69 void solve()
    70 {
    71     int out[MAXN];
    72     memset(out,0,sizeof(out));
    73     for (int i=0;i<m;i++)
    74         if (b[u[i]]!=b[v[i]])
    75         {
    76             out[b[u[i]]]++;
    77         }
    78  
    79     int noout=0;
    80     int res;
    81     for (int i=0;i<=cnt;i++)
    82         if (out[i]==0)
    83         {
    84             res=i;
    85             noout++;
    86         }
    87     if (noout==1) cout<<sum[res]<<endl;
    88         else cout<<0<<endl;
    89 }
    90  
    91 int main()
    92 {
    93     init();
    94     for (int i=1;i<=n;i++) if (vis[i]==0) tarjan(i);
    95     solve();
    96     return 0;
    97 } 
  • 相关阅读:
    请求报文的方法及get与post的区别
    fiddler响应报文的headers属性详解
    fiddler请求报文的headers属性详解
    Session与Cookie的区别
    python学习之函数(四)--递归
    python学习之函数(四)--lambda表达式
    python学习之函数(三)--函数与过程
    python学习之函数(二)——参数
    python学习之序列
    python学习之函数(一)
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5205802.html
Copyright © 2011-2022 走看看