#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; const int maxn=1111;//有多少个结点 vector<int>G[maxn]; int visited[maxn];//标记该节点有没有访问过 int node,edge;//顶点数目 int tmpdfn;//dfs过程中记录当前的深度优先搜索序数 int dfn[maxn];//记录每个顶点的深度优先搜索序数 int low[maxn];//每个顶点的low值,根据该值来判断是否是关节点 int son;//根结点的有多少个孩子,如果大于等于2,则根结点为关节点 int subnets[maxn];//记录每个结点(去掉该结点后)的连通分量的个数 void init() { for(int i=0;i<maxn;i++) G[i].clear(); low[1]=dfn[1]=1; tmpdfn=1;son=0; memset(visited,0,sizeof(visited)); visited[1]=1; memset(subnets,0,sizeof(subnets)); } void dfs(int u) { for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!visited[v]) { visited[v]=1; tmpdfn++; dfn[v]=low[v]=tmpdfn; dfs(v); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]) { if(u!=1) subnets[u]++; if(u==1) son++; } } else low[u]=min(low[u],dfn[v]); } } int main() { scanf("%d%d",&node,&edge);//输入节点数量和边的数量 init();//初始化 for(int i=1;i<=edge;i++) { int u,v; scanf("%d%d",&u,&v); //无向图建边 G[u].push_back(v); G[v].push_back(u); } //求解割点 dfs(1); //计算根节点 if(son>1) subnets[1]=son-1; for(int i=1;i<=node;i++) if(subnets[i]) printf("%d号节点是割点,删除之后有%d个连通分量\n",i,subnets[i]+1); return 0; }
时间: 2024-11-05 18:45:48