模板 无向图删掉一个顶点之后连通块的最大个数

只有当一个顶点是割点的时候,删掉这个点才可以增加图中连通块的个数
(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;
}
原文地址:https://www.cnblogs.com/fxq1304/p/13636671.html