zoukankan      html  css  js  c++  java
  • ACM模板——强连通分量

     1 vector<int> G[maxn];
     2 vector<int> rG[maxn];
     3 vector<int> vs;
     4 vector<int> ans[maxn];
     5 bool used[maxn];
     6 int V,E;
     7 int rnt = 0;
     8 void add_edge(int from,int to)
     9 {
    10     G[from].pb(to);
    11     rG[to].pb(from);
    12 }
    13 void dfs(int v)
    14 {
    15     used[v] = true;
    16     _for(i,0,G[v].size())
    17         if(!used[G[v][i]])
    18             dfs(G[v][i]);
    19     vs.pb(v);
    20 }
    21 void rdfs(int v,int k)
    22 {
    23     used[v] = true;
    24     ans[k].pb(v);
    25     _for(i,0,rG[v].size())
    26         if(!used[rG[v][i]])
    27             rdfs(rG[v][i],k);
    28 }
    29 //第k个集合里有哪些节点 ans[k]
    30 //rnt为最大集合的集合大小
    31 void Kosaraju()
    32 {
    33     memset(used,0,sizeof(used));
    34     _for(v,1,V+1)
    35         if(!used[v])
    36             dfs(v);
    37     
    38     memset(used,0,sizeof(used));
    39     int k = 0;
    40     _rep(i,vs.size()-1,-1)
    41         if(!used[vs[i]])
    42         {
    43             rdfs(vs[i],k);
    44             rnt = max(rnt,(int)ans[k].size());
    45             k ++;
    46         }
    47 }
    Kosaraju
     1 int N,M;
     2 int ver[maxn],Next[maxn],head[maxn],dfn[maxn],low[maxn];
     3 int Gver[maxn],GNext[maxn],Ghead[maxn],Gtot;
     4 int stack[maxn],ins[maxn],c[maxn];
     5 vector<int> scc[maxn];
     6 int tot,top,cnt,nm;
     7 //cnt个强连通分量,scc[i]记录编号为i的强连通分量中的所有节点,c[x]表示x所在连通分量地区
     8 void addori(int x,int y)
     9 {
    10     ver[++tot] = y,Next[tot] = head[x],head[x] = tot;
    11 }
    12 void tarjan(int x)
    13 {
    14     dfn[x] = low[x] = ++nm;
    15     stack[++top] = x,ins[x] = 1;
    16     for(int i = head[x]; i; i = Next[i])
    17     {
    18         int y = ver[i];
    19         if(!dfn[y])
    20         {
    21             tarjan(y);
    22             low[x] = min(low[x],low[y]);
    23         }
    24         else if(ins[y])
    25             low[x] = min(low[x],dfn[y]);
    26     }
    27     if(dfn[x] == low[x])
    28     {
    29         cnt ++;
    30         int y;
    31         do
    32         {
    33             y = stack[top --],ins[y] = 0;
    34             c[y] = cnt,scc[cnt].pb(y);
    35         }
    36         while(x != y);
    37     }
    38 }
    39 void addAft(int x,int y)
    40 {
    41     Gver[++Gtot] = y;
    42     GNext[Gtot] = Ghead[x];
    43     Ghead[x] = Gtot;
    44 }
    45 void Shrink()
    46 {
    47     _for(i,1,N+1)
    48     if(!dfn[i])
    49         tarjan(i);
    50 
    51     _for(x,1,N+1)
    52     for(int i = head[x]; i; i = Next[i])
    53     {
    54         int y = ver[i];
    55         if(c[x]==c[y]) continue;
    56         addAft(c[y],c[x]);
    57     }
    58 }
    Tarjan 缩点
  • 相关阅读:
    IE hasLayout详解
    seajs引入jquery
    jquery实现轮播插件
    CSS视觉格式化模型
    js事件冒泡和事件捕获详解
    你尽力了么===BY cloudsky
    前向否定界定符 python正则表达式不匹配某个字符串 以及无捕获组和命名组(转)
    php safe mode bypass all <转>
    WAF指纹探测及识别技术<freebuf>
    linux集群管理<转>
  • 原文地址:https://www.cnblogs.com/Asurudo/p/11536005.html
Copyright © 2011-2022 走看看