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 }
  • 相关阅读:
    karto 资料
    底盘运动学
    QT中搜索文件列表
    Qt中引入boost库
    AGV调度理论链接
    qt开发杂记
    C++代码读取ping的网络延时
    结构体解析数据
    QJson 的简单使用
    Vue中问题总结 与未解决问题总结
  • 原文地址:https://www.cnblogs.com/WABoss/p/5155736.html
Copyright © 2011-2022 走看看