• poj 2186 Popular Cows 强连通缩点


    【题意】;给出一群牛中,一头牛认为另一头牛受欢迎的m对关系,关系式可以传递的,即若a认为b受欢迎,b认为c受欢迎,那么a也认为c受欢迎。求最多有多少头牛被所有的牛认为受欢迎。

    【思路】:把这些关系形成的强连通图缩成点,就形成了一有向无环图,这个图里的出度为0的点(有且只有一个)就是被所有牛认为受欢迎的点,说明若这个点原来是强连通图就要求出这个强连通图里的总点数,

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<string.h>
     4 #include<stack>
     5 using namespace std;
     6 
     7 int pre[10002],low[10002],lt_num,c,scc_num[10002],scc,out0[10002],n,adj[10002],num,flag,scc_count[10002];
     8 struct E
     9 {
    10     int to;
    11     int next;
    12 } edge[500000];
    13 
    14 stack <int >s;
    15 
    16 void add(int a,int b)
    17 {
    18     edge[num].to=b;
    19     edge[num].next=adj[a];
    20     adj[a]=num++;
    21 }
    22 
    23 void dfs(int u)
    24 {
    25     int i,v;
    26     pre[u]=low[u]=c++;
    27     s.push (u);
    28     for(i=adj[u]; i!=-1; i=edge[i].next)
    29     {
    30         v=edge[i].to;
    31         if(!pre[v])//!scc_num[v]
    32         {
    33             dfs(v);
    34 
    35                 low[u]=min(low[u],low[v]);
    36         }
    37         else if(!scc_num[v])
    38             low[u]=min(low[u],pre[v]);
    39     }
    40     if(low[u]==pre[u])   //是该连通分量的 第一个点
    41     {
    42         scc++;
    43         while(1)
    44         {
    45             int t=s.top ();
    46             s.pop ();
    47             scc_num[t]=scc;             //scc_num[t]是第scc个强连通分量;
    48             scc_count[scc]++;
    49             if(t==u)
    50                 break;
    51         }
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     int a,b,m,i;
    58     while(~scanf("%d%d",&n,&m))
    59     {
    60         memset(adj,-1,sizeof(adj));
    61         num=0;
    62         while(m--)
    63         {
    64             scanf("%d%d",&a,&b);
    65             add(a,b);
    66         }
    67         c=1;scc=0;
    68         memset(scc_count,0,sizeof(scc_count));
    69         memset(pre,0,sizeof(pre));
    70         for(int i=1;i<=n;i++)
    71             if(pre[i]==0)
    72                 dfs(i);
    73 
    74 
    75         memset(out0,0,sizeof(out0));
    76         for(int u=1;u<=n;u++)
    77             for(i=adj[u]; i!=-1; i=edge[i].next)
    78             {
    79                 int v; v=edge[i].to;
    80                 if(scc_num[u]!=scc_num[v])
    81                     out0[scc_num[u]]++;
    82             }
    83 
    84         int ans=0,num=0;
    85         for(int u=1;u<=scc;u++)
    86             if(out0[u]==0)
    87                 {
    88                     num++;
    89                     ans+=scc_count[u];
    90                 }
    91                 if(num==1)
    92         printf("%d
    ",ans);
    93         else printf("0
    ");
    94     }
    95     return 0;
    96 }
  • 相关阅读:
    Oracle与MySQL的转化差异
    iOS 创建静态库文件时去掉当中的Symbols
    hdu4336 Card Collector 状态压缩dp
    随机森林——Random Forests
    OpenCV码源笔记——Decision Tree决策树
    海明距离hamming distance
    学习OpenCV——Surf简化版
    学习OpenCV——用OpenCv画漫画
    学习OpenCV——ORB简化版&Location加速版
    学习OpenCV——hand tracking手势跟踪
  • 原文地址:https://www.cnblogs.com/assult/p/3871030.html
Copyright © 2020-2023  润新知