2020ICPC·Xiaomi Internet Trial Tournament D Question Router Mesh【Tarjan find cut point and subtree】

Portal: Router Mesh

Title

Give you an undirected graph, you need to ask to delete every time iiAfter the point i (i=1,2,...,n), how many connected components are there.

Ideas

  • Every time dfs dfsd f s can search for a connected component, and find each pointuuu in the depth-first search spanning treedownwith achild [u] child [u]c h i l d [ u ] subtree branches. Indfs dfsD F S process, only when!dfn[u]&&low[v]>=dfn[u]onlychild[u]++(see Code), as thischild [u] child [u]c h i l d [ u ] The statistics areuuu pointsubtreenumber.
  • If you delete the point uuu is the root node, obviously it is the cut point, after deleting it, the number of new connected components ischild [u] child [u]child[u]
  • Otherwise, the number of new connected components after deletion is child [u] + 1 child[u]+1child[u]+1 because there is a connected component above it.

AC code

#include <bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int n,m;
vector<int>g[N];
bool fa[N];
int dfn[N],low[N];
int tim=0;
int child[N]; // 每个点的子树个数
void dfs(int u)
{
    
    
    dfn[u]=low[u]=++tim;
    int sz=g[u].size();
    for(int i=0;i<sz;i++)
    {
    
    
        int v=g[u][i];
        if(!dfn[v])
        {
    
    
            dfs(v);
            low[u]=min(low[u],low[v]);
            if(low[v]>=dfn[u])
            	child[u]++;
        }
        else // 回退边
        {
    
    
            low[u]=min(low[u],dfn[v]);
        }
    }
}
void solve()
{
    
    
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
    
    
        if(!dfn[i])
        {
    
    
            cnt++; // 初始时所有连通块个数
            fa[i]=1; // i是这个连通块的祖先节点
            dfs(i);
        }
    }
    for(int i=1;i<=n;i++)
    {
    
    
        if(fa[i])
        {
    
    
            child[i]=cnt-1+child[i];
        }
        else
        {
    
    
            child[i]=cnt-1+child[i]+1;
        }
    }
}
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin>>n>>m;
    int x,y;
    for(int i=1;i<=m;i++)
    {
    
    
        cin>>x>>y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    solve();
    for(int i=1;i<=n;i++)
        i==n?printf("%d\n",child[i]):printf("%d ",child[i]);
    return 0;
}
/*
5 1
1 2
ans:4 4 3 3 3

6 5
1 2
2 3
3 1
4 5
5 6
ans:2 2 2 2 3 2
*/

There is also a wave of mentality caused by Niuke’s compilation environment: If you write the return value of the dfs function as int, and then do not return, there is no problem with Luogu’s online IDE and local codeblocks, and it will give you an error when submitted to Niuke (Segmentation error or timeout).

Guess you like

Origin blog.csdn.net/ljw_study_in_CSDN/article/details/109279214