去掉每个点以后的连通分支数

题目链接:点击这里
在这里插入图片描述
输入样例:

4 2
1 2
1 3

输出样例:

3 2 2 1

代码如下

#include <cstdio>
#include <cstring>
#include <vector>
#include<iostream>
#include <algorithm>
#define maxd 300000+5
using namespace std;
int low[maxd],num[maxd],dfn=0,tot=0;
bool vis[maxd];
vector<int>G[maxd];
vector<int>Gra[maxd];
int block[maxd];
bool iscut[maxd];
void dfs(int u){
    int rc=0;
    num[u]=low[u]=++dfn;
    for (int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if (!num[v]){
            dfs(v);
            
            low[u]=min(low[u],low[v]);
            if (low[v]>=num[u]) {
				block[u]++;
			}
            
        }
        else low[u]=min(low[u],num[v]);
    }    
}//block[0]代表原图的连通分支数 
void dfs2(int u){
    int rc=0;
    num[u]=low[u]=++dfn;
    for (int i=0;i<Gra[u].size();i++){
        int v=Gra[u][i];
        vis[v]=true;
        if (!num[v]){
            dfs2(v);
            
            low[u]=min(low[u],low[v]);
            if (low[v]>=num[u]) {
				block[u]++;
			}
            
        }
        else low[u]=min(low[u],num[v]);
    }    
}
int main() {
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;++i) block[i]=1;
	
	for(int i=1;i<=n;++i){
		G[0].push_back(i);
		G[i].push_back(0);
	}
	
	for(int i=0;i<m;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		Gra[u].push_back(v);
		Gra[v].push_back(u);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(0);	
	memset(low,0,sizeof(low));
	memset(num,0,sizeof(num));
	dfn=0;
	for(int i=1;i<=n;++i){
		block[i]=block[0];
	}
	for(int i=1;i<=n;++i){
		if(!vis[i]){
			block[i]--;
			dfs2(i);
		}
	}
	for(int i=1;i<=n;++i){
		printf("%d ",block[i]);
	}
    return 0;
}




#include <cstdio>
#include <cstring>
#include <vector>
#include<iostream>
#include <algorithm>
#define maxd 300000+5
using namespace std;
int low[maxd],num[maxd],dfn=0,tot=0;
int numof=0; 
bool vis[maxd];
vector<int>Gra[maxd];
int block[maxd];
bool iscut[maxd];
void dfs2(int u){
	if(!vis[u]) numof++;
    int rc=0;
    num[u]=low[u]=++dfn;
    for (int i=0;i<Gra[u].size();i++){
        int v=Gra[u][i];
        vis[v]=true;
        if (!num[v]){
            dfs2(v);
            
            low[u]=min(low[u],low[v]);
            if (low[v]>=num[u]) {
				block[u]++;
			}
            
        }
        else low[u]=min(low[u],num[v]);
    }    
}//block[0]代表原图的连通分支数 
int main() {
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++){
		int u,v;
		scanf("%d %d",&u,&v);
		Gra[u].push_back(v);
		Gra[v].push_back(u);
	}
	memset(low,0,sizeof(low));
	memset(num,0,sizeof(num));
	dfn=0;
	for(int i=1;i<=n;++i){
		if(!vis[i]){
			block[i]--;
			dfs2(i);
		}
	}
	for(int i=1;i<=n;++i) block[i]+=numof;
	for(int i=1;i<=n;++i){
		printf("%d ",block[i]);
	}
    return 0;
}
©️2020 CSDN 皮肤主题: 数字20 设计师:CSDN官方博客 返回首页