zoukankan      html  css  js  c++  java
  • POJ2186 Popular Cows(强连通分量)

    题目问一个有向图所有点都能达到的点有几个。

    先把图的强连通分量缩点,形成一个DAG,那么DAG“尾巴”(出度0的点)所表示的强连通分量就是解,因为前面的部分都能到达尾巴,但如果有多个尾巴那解就是0了,因为尾巴间达到不了。判断是否有多个尾巴,可以从最后一个强连通分量中的某一个点出发看能否在逆图上遍历完其他点。

    因为用到了逆图,所以直接用Kosaraju算法。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<vector>
     4 #include<algorithm>
     5 using namespace std;
     6 #define MAXM 111111
     7 #define MAXN 11111
     8 struct Edge{
     9     int v,next;
    10 }edge[MAXM];
    11 int NE,head[MAXN],rhead[MAXN];
    12 void addEdge(int u,int v){
    13     edge[NE].v=v; edge[NE].next=head[u]; head[u]=NE++;
    14     edge[NE].v=u; edge[NE].next=rhead[v]; rhead[v]=NE++;
    15 }
    16 
    17 int belong[MAXN];
    18 bool vis[MAXN];
    19 vector<int> post;
    20 void dfs(int u){
    21     vis[u]=1;
    22     for(int i=head[u]; i!=-1; i=edge[i].next){
    23         int v=edge[i].v;
    24         if(vis[v]) continue;
    25         dfs(v);
    26     }
    27     post.push_back(u);
    28 }
    29 void rdfs(int u,int k){
    30     vis[u]=1; belong[u]=k;
    31     for(int i=rhead[u]; i!=-1; i=edge[i].next){
    32         int v=edge[i].v;
    33         if(vis[v]) continue;
    34         rdfs(v,k);
    35     }
    36 }
    37 int rdfs(int u){
    38     int res=1;
    39     vis[u]=1;
    40     for(int i=rhead[i]; i!=-1; i=edge[i].next){
    41         int v=edge[i].v;
    42         if(vis[v]) continue;
    43         res+=rdfs(v);
    44     }
    45     return res;
    46 }
    47 int scc(int n){
    48     memset(vis,0,sizeof(vis));
    49     post.clear();
    50     for(int i=1; i<=n; ++i){
    51         if(!vis[i]) dfs(i);
    52     }
    53     memset(vis,0,sizeof(vis));
    54     int k=0;
    55     for(int i=post.size()-1; i>=0; --i){
    56         int v=post[i];
    57         if(!vis[v]) rdfs(v,++k);
    58     }
    59     memset(vis,0,sizeof(vis));
    60     for(int i=1; i<=n; ++i){
    61         if(belong[i]==k){
    62             if(rdfs(i)!=n) return 0;
    63             break;
    64         }
    65     }
    66     int res=0;
    67     for(int i=1; i<=n; ++i){
    68         if(belong[i]==k) ++res;
    69     }
    70     return res;
    71 }
    72 int main(){
    73     memset(head,-1,sizeof(head));
    74     memset(rhead,-1,sizeof(rhead));
    75     int n,m,a,b;
    76     scanf("%d%d",&n,&m);
    77     while(m--){
    78         scanf("%d%d",&a,&b);
    79         addEdge(a,b);
    80     }
    81     printf("%d",scc(n));
    82     return 0;
    83 }
  • 相关阅读:
    第07组 Alpha冲刺(2/6)
    第07组 Alpha冲刺(1/6)
    第07组 团队Git现场编程实战
    团队项目-需求分析报告
    团队项目-选题报告
    [面试]快来测测你的C++水平
    [技术博客] 数据库1+N查询问题
    【Beta】Scrum meeting 10
    【Beta】Scrum meeting 9
    [技术博客] gitlab快速部署流程
  • 原文地址:https://www.cnblogs.com/WABoss/p/5155736.html
Copyright © 2011-2022 走看看