图论-1 求连通分量

DFS框架:
     
     vector<int>  G[maxn];
     int vis[maxn];
     

     void dfs(int u)
     {
          vis[u] = 1;
          PREVISIT(u);
          int d = G[u].size();
          for(int  i = 0; i < d; i++)
          {
               int v = G[u][i];
               if(!vis[i])
                    dfs(i);
          }
          POSTVISIT(u);
     }

G[u][i]表示节点u的第i个子节点
可以将递归改称非递归防止溢出



在无向图中,如果可以从节点u到节点v,那么从节点v也必定可以到达节点u,(反过来走):如果节点u到极点v,而节点v又可以到达节点w,则节点u可以到达节点w,再加上每个节点可以从可以到达本身。证明了在无向图中可达关系满足自反性,对称性和传递性。这在离散中是一个等价关系。

从等价关系定义等价类。我们可以把互相到达的节点称为一个连通分量。很容易用DFS在线性时间内求出任意无向图的连通分量。

void  find_cc()
{
     current_cc = 0;
     memset(vis,0,sizeof(vis));
     for(int u = 0; u < n; u++)  //检查图中的每个节点
          if(!vis[u])             //如果节点u没有访问过,意味着属于一个新的连通分量
          {
               current_cc++;     //连通分量的数量
               dfs(u);               //从节点u开始DFS可以访问到它所在的整个连通分量
          }
}

这里有个全局的变量current_cc表示当前连通分量的编号。
如果要记录每个节点的连通分量的数量,就需要在PREVISIT(u)中赋值
cc[u] = current_cc;

如果只求连通分量,使用并查集比较快
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值