zoukankan      html  css  js  c++  java
  • Tarjan

    强连通

    定义:

    有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。

    如果有向图G的每两个顶点都强连通,称G是一个强连通图。

    有向图的极大强连通子图,称为强连通分量(strongly connected components)。

     1 void tarjan(int cur){
     2     dfn[cur] = low[cur] = ++t_cnt;
     3     stack[++s_size] = cur; instack[cur] = 1;
     4     for(int i = head[cur]; i != -1; i = edge[i].next){
     5         int v = edge[i].v;
     6         if(!dfn[v]){
     7             tarjan(v);
     8             low[cur] = min(low[cur], low[v]);
     9         }
    10         else if(instack[v])//栈里的是来时路上的点 当然可以到达当前点 所以可以更新
    11             low[cur] = min(low[cur], low[v]);
    12     }
    13     if(dfn[cur] == low[cur]){
    14         col_size++;
    15         do{
    16             int temp = stack[s_size];
    17             color[temp] = col_size;
    18             instack[temp] = 0;
    19         }while(stack[s_size--] != cur);
    20     }
    21 }
    强连通(包括染色

    双联通

    双连通分量又分 点双连通分量 和 边双连通分量 两种。

    若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图。

    说白了就是找环啦

    一个无向图中的每一个极大点(边)双连通子图称作此无向图的点(边)双连通分量。

    这里就不附带代码了 因为和找割点极为类似

    缩点

    其实就是把一个强连通分量缩成一个点

     1 void tarjan(int cur){
     2     dfn[cur] = low[cur] = ++t_cnt;
     3     stack[++s_size] = cur; instack[cur] = 1;
     4     for(int i = head[cur]; i != -1; i = edge[i].next){
     5         int v = edge[i].v;
     6         if(!dfn[v]){
     7             tarjan(v);
     8             low[cur] = min(low[cur], low[v]);
     9         }
    10         else if(instack[v])
    11             low[cur] = min(low[cur], low[v]);
    12     }
    13     if(dfn[cur] == low[cur]){
    14         col_size++;
    15         do{
    16             int temp = stack[s_size];
    17             color[temp] = col_size;
    18             nw[col_size] += w[temp];//只多这一句话
    19             instack[temp] = 0;
    20         }while(stack[s_size--] != cur);
    21     }
    22 }
    缩点

    割点

     1 void tarjan(int x, int fa){
     2     int ch = 0;
     3     dfn[x] = low[x] = ++t_cnt;
     4     for(int i = head[x]; i != -1; i = edge[i].next){
     5         int vv = edge[i].v;
     6         if(vv == fa)continue;
     7         if(!dfn[vv]){
     8             ch++;
     9             tarjan(vv, x);
    10             low[x] = min(low[x], low[vv]);
    11             if(low[vv] >= dfn[x]) cut[x] = 1;
    12         }
    13         low[x] = min(low[x], dfn[vv]);//关键是这里!与强连通不同
    14     }
    15     if(fa == -1 && ch <= 1) cut[x] = 0;
    16 }
    割点

    lca

     1 void tarjan(int x){
     2     vis[x] = 1;
     3     for(int i = head[x]; i != -1; i = edge[i].next){
     4         int vv = edge[i].v;
     5         if(vis[vv]) continue;
     6         tarjan(vv);
     7         fa[vv] = x;
     8     }
     9     for(int i = hq[x]; i != -1; i = q[i].next){
    10         int vv = q[i].v;
    11         if(vis[vv]) ans[q[i].id] = find(vv);
    12     }
    13 }
    LCA

    相关题目:

  • 相关阅读:
    unity3d引擎中slua的使用
    分布式理论之一:Paxos算法的通俗理解
    ZIP压缩算法详细分析及解压实例解释
    MapReduce剖析笔记之八: Map输出数据的处理类MapOutputBuffer分析
    MapReduce剖析笔记之七:Child子进程处理Map和Reduce任务的主要流程
    MapReduce剖析笔记之六:TaskTracker初始化任务并启动JVM过程
    MapReduce剖析笔记之五:Map与Reduce任务分配过程
    MapReduce剖析笔记之四:TaskTracker通过心跳机制获取任务的流程
    Hadoop2.2.0安装过程记录
    序列化笔记之一:Google的Protocol Buffer格式分析
  • 原文地址:https://www.cnblogs.com/hjmmm/p/9190101.html
Copyright © 2011-2022 走看看