zoukankan      html  css  js  c++  java
  • 模板 无向图删掉一个顶点之后连通块的最大个数

    只有当一个顶点是割点的时候,删掉这个点才可以增加图中连通块的个数
    (tarjan)算法计算割点的过程中,对于一个顶点(u)
    1.如果(u)不是根,每当出现一个子节点&v&,(low[v]>=dfn[u])时,说明删掉(u)会使得连通块个数增加1,所以删掉(u)之后连通块个数的增加值为这样的(v)的个数
    2.如果(u)是根,因为原先连通块的个数为(1),删掉(u)之后,连通块个数变成(dfs)树中子节点的个数,也就是(child),所以连通块个数的增加值为((child-1))
    设全局变量(sum)为删掉一个点可以增加的连通块个数的最大值,通过(tarjan)算法计算删掉每个点之后增加的连通块的值,更新(sum)
    最终结果为原本的连通块个数加上(sum)的值
    (ps:)由于可能存在孤立的点,删掉这些点之后增加的连通块个数为(-1),所以将(sum)的初始值设为(-1)

    const int maxn=100010;
    int dfn[maxn],low[maxn],dfscnt;
    int sum;
    
    void tarjan(int u,int fa){
        dfn[u]=low[u]=++dfscnt;
        int child=0,cur=0;
        for(int i=head[u];~i;i=nxt[i]){
            int v=to[i];
            if(!dfn[v]){
                child++;
                tarjan(v,u);
                low[u]=min(low[u],low[v]);
                if(low[v]>=dfn[u]) cur++;
            }
            else if(v!=fa){
                low[u]=min(low[u],dfn[v]);
            }
        }
        if(fa==-1) sum=max(sum2,cur-1);
        else sum=max(sum,cur);
    }
    
    int solve(){
        int ans=0;
        sum=-1;
        for(int i=0;i<n;i++){
            if(!dfn[i]){
                ans++;
                tarjan(i,-1);
            }
        }
        ans+=sum;
        return ans;
    }
    
  • 相关阅读:
    (二分)进击的奶牛
    (二分)木材加工
    (简单并查集)The Suspects
    (递归)集合划分
    (简单并查集)How many tables?
    Wireless Network(并查集)
    (并查集)连通块中点的数量
    2019.04.08 电商17 购物车模型
    2019.04.08 电商 16 地址管理2
    2019.04.07 电商15 地址管理
  • 原文地址:https://www.cnblogs.com/fxq1304/p/13636671.html
Copyright © 2011-2022 走看看