• POJ 2186 Popular Cows(强连通分量缩点)


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

    题目意思大概是:给定N(N<=10000)个点和M(M<=50000)条有向边,求有多少个“受欢迎的点”。所谓的“受欢迎的点”当且仅当任何一个点出发都能到达它。

    原来的图是无序且可能有环,用tarjan缩点,变成一个DAG。受欢迎点的出度一定为0,所以缩点后求有多少个连通分量的出度是0,要是大于1则没有受欢迎的点,等于1的话求出这个出度为0的连通分量有多少个点。

    强联通分量tarjan算法里邻接表用vector一般好理解,但是速度不及链式前向星,链式前向星学习链接:http://blog.csdn.net/acdreamers/article/details/16902023

    AC代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 const int MAXN = 1e4 + 5;
     7 struct data {
     8     int next , to;
     9 }edge[MAXN * 5];
    10 int head[MAXN] , low[MAXN] , dfn[MAXN] , block[MAXN] , st[MAXN];
    11 int top , ord , sccnum;
    12 bool instack[MAXN] , out[MAXN];
    13 
    14 void init(int n) {
    15     for(int i = 1 ; i <= n ; i++) {
    16         low[i] = dfn[i] = 0;
    17         head[i] = -1;
    18         instack[i] = false;
    19     }
    20     top = ord = sccnum = 0;
    21 }
    22 
    23 void tarjan(int u) {
    24     low[u] = dfn[u] = ++ord;
    25     st[++top] = u;
    26     instack[u] = true;
    27     for(int i = head[u] ; ~i ; i = edge[i].next) { //链式前向星
    28         int v = edge[i].to;
    29         if(!dfn[v]) {
    30             tarjan(v);
    31             low[u] = min(low[u] , low[v]);
    32         }
    33         else if(instack[v]) {
    34             low[u] = min(low[u] , dfn[v]);
    35         }
    36     }
    37     if(low[u] == dfn[u]) {
    38         int v;
    39         sccnum++;
    40         do {
    41             v = st[top--];
    42             instack[v] = false;
    43             block[v] = sccnum;
    44         }while(u != v);
    45     }
    46 }
    47 
    48 int main()
    49 {
    50     int n , m , u , v;
    51     while(~scanf("%d %d" , &n , &m)) {
    52         init(n);
    53         for(int i = 0 ; i < m ; i++) {
    54             scanf("%d %d" , &u , &v);
    55             edge[i].to = v;     //链式前向星
    56             edge[i].next = head[u];
    57             head[u] = i;
    58         }
    59         for(int i = 1 ; i <= n ; i++) {
    60             if(!dfn[i])
    61                 tarjan(i);
    62         }
    63         memset(out , false , sizeof(out)); //缩点是否有入度
    64         for(int u = 1 ; u <= n ; u++) {
    65             for(int i = head[u] ; ~i ; i = edge[i].next) { //链式前向星
    66                 int v = edge[i].to;
    67                 if(block[v] != block[u])  //不是同一个连通分量
    68                     out[block[u]] = true;
    69             }
    70         }
    71         int res = 0 , op = -1;
    72         for(int i = 1 ; i <= sccnum ; i++) {
    73             if(!out[i]) {  //出度为0的点
    74                 res++;
    75                 op = i;
    76             }
    77         }
    78         if(res > 1) {
    79             printf("0
    ");
    80         }
    81         else {
    82             res = 0;
    83             for(int i = 1 ; i <= n ; i++) {
    84                 if(block[i] == op)
    85                     res++;
    86             }
    87             printf("%d
    " , res);
    88         }
    89     }
    90 }
  • 相关阅读:
    《神经网络设计》读书笔记第一章
    <转>How to Encourage Your Child's Interest in Science and Tech
    <转>卷积神经网络是如何学习到平移不变的特征
    卷积神经网络物体检测之感受野大小计算
    神经网络向量化求反向传播梯度
    SSD框架训练自己的数据集
    object detect links
    Computer vision labs
    Deep Learning Blog lists
    YOLO: Real-Time Object Detection
  • 原文地址:https://www.cnblogs.com/Recoder/p/5255728.html
Copyright © 2020-2023  润新知