• POJ 2186 Popular Cows(强联通分量)


    题目链接:http://poj.org/problem?id=2186

    题目大意:

       每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
    种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
    牛被所有的牛认为是受欢迎的。
    解题思路:
    假设有两头牛A和B都被其他所有牛认为是红人,那么显然,A被B认为是红人,B也被A认为是红人,即存在一个包含A、B两个顶点的圈,或者说,A、B同属于一个强联通分量。所以
    如果有一头牛被其他所有牛认为是红人,那么其所属的强联通分量内的所有牛都被其他所有牛认为是红人。我们把图进行强联通分量分解后,至多有一个强联通分量满足题目的条件。
    做法: 先用tarjan求出每个强连通分量,再缩点,统计每个点的出度,如果有且只有1个出度为0的点,就输出这个点包含的节点数,否则输出0。
    代码
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<vector>
     6 #include<stack>
     7 using namespace std;
     8 const int N=1e4+5;
     9 
    10 int cnt,num;
    11 int dfn[N],low[N],fa[N],sze[N],outdeg[N];
    12 stack<int>sk;
    13 vector<int>v[N];
    14 
    15 void tarjan(int u){
    16     dfn[u]=low[u]=++cnt;
    17     sk.push(u);
    18     for(int i=0;i<v[u].size();i++){
    19         int t=v[u][i];
    20         if(!dfn[t]){                                        //点t未被访问
    21             tarjan(t);
    22             low[u]=min(low[u],low[t]);
    23         }
    24         else if(!fa[t])  low[u]=min(low[u],dfn[t]);         //点t已被访问,且t还在栈中
    25     }
    26     if(low[u]==dfn[u]){
    27         num++;
    28         while(1){
    29             int t=sk.top();
    30             sk.pop();
    31             fa[t]=num;                                      //缩点操作,将这些点都归为点num
    32             sze[num]++;
    33             if(t==u) break;
    34         }
    35     }
    36 }
    37 
    38 int main(){
    39     int n,m;
    40     scanf("%d%d",&n,&m);
    41     for(int i=1;i<=m;i++){
    42         int a,b;
    43         scanf("%d%d",&a,&b);
    44         v[a].push_back(b);
    45     }
    46     for(int i=1;i<=n;i++){
    47         if(!dfn[i]) tarjan(i);
    48     }
    49     for(int i=1;i<=n;i++){
    50         for(int j=0;j<v[i].size();j++){
    51             int t=v[i][j];
    52             if(fa[t]!=fa[i]) outdeg[fa[i]]++;
    53         }
    54     }
    55     //缩点后,出度为0的点只能有一个,否则不符合条件输出0
    56     int ans=0;
    57     for(int i=1;i<=num;i++){
    58         if(!outdeg[i]){
    59             if(ans>0){
    60                 puts("0");
    61                 return 0;
    62             }
    63             ans=sze[i];
    64         }
    65     }
    66     printf("%d
    ",ans);
    67     return 0;
    68 }
     
     
  • 相关阅读:
    [转]javaweb学习总结(二十二)——基于Servlet+JSP+JavaBean开发模式的用户登录注册
    [转]javaweb学习总结(二十一)——JavaWeb的两种开发模式
    [转]javaweb学习总结(二十)——JavaBean总结
    [转]javaweb学习总结(十九)——JSP标签
    [转]javaweb学习总结(十八)——JSP属性范围
    [转]JavaWeb学习总结(十七)——JSP中的九个内置对象
    [转]javaweb学习总结(十六)——JSP指令
    [转]javaweb学习总结(十五)——JSP基础语法
    TypeScript
    TypeScript
  • 原文地址:https://www.cnblogs.com/fu3638/p/8635597.html
Copyright © 2020-2023  润新知