题目大意:无向图 删去每个节点 剩下联通块的个数
题解:Tarjian时统计,若当前节点不是根结点,ans[x]初始值为1,因为删去x后,父亲会成单独一部分。
代码:
// // 1.cpp // zyh // // Created by cumt24 on 2020/10/26. // Copyright © 2020年 cumt24. All rights reserved. // #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define N 300008 using namespace std; int n,m; int sumedge,js,root,tim; int head[N],ans[N],dfn[N],low[N]; struct Edge { int x,y,nxt; Edge(int x=0,int y=0,int nxt=0): x(x),y(y),nxt(nxt){} }edge[N<<1]; void add(int x,int y) { edge[++sumedge]=Edge(x,y,head[x]); head[x]=sumedge; } void Tarjian(int x,int fa) { dfn[x]=low[x]=++tim; ans[x]=x!=root; for(int i=head[x];i;i=edge[i].nxt) { int v=edge[i].y; if(v==fa) continue; if(!dfn[v]) { Tarjian(v,x); low[x]=min(low[x],low[v]); if(low[v]>=dfn[x])ans[x]++; }else low[x]=min(low[x],dfn[v]); } } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add(x,y); add(y,x); } for(int i=1;i<=n;i++) { if(!dfn[i]) { js++; root=i; Tarjian(i,-1); } } for(int i=1;i<=n;i++) { printf("%d ",js-1+ans[i]); } return 0; }