题意就是求出在一个图上去除一个点之后,那个图会变成多少个子连通图。
显然我们要求出割顶。我的代码套用了刘汝佳的大白书的tarjan算法,用一个数组cnt[]记录一个点是多少个点双连通分量的割顶。当发现一个点是割顶的时候,就cnt[i]++。最后,如果一个点是一棵dfs树的树根时,就输出cnt[i],否则就输出cnt[i]+1(因为那个点有父亲,而cnt数组记录的相当于是该点的儿子个数)。
?
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std; struct Edge { int u,v; Edge(int uu,int vv) { u=uu;v=vv; } Edge(){} }; const int maxn=1005; int pre[maxn],iscut[maxn],bccno[maxn],dfs_clock,bcc_cnt; vector
G[maxn],bcc[maxn]; vector
> ans; int cnt[maxn]; bool isfa[maxn]; stack
s; int dfs(int u,int fa) { int lowu=pre[u]=++dfs_clock; int child=0; for(int i=0;i
=pre[u]) { iscut[u]=true;cnt[u]++; bcc_cnt++;bcc[bcc_cnt].clear(); for(;;) { Edge x=s.top();s.pop(); if(bccno[x.u]!=bcc_cnt){bcc[bcc_cnt].push_back(x.u);bccno[x.u]=bcc_cnt;} if(bccno[x.v]!=bcc_cnt){bcc[bcc_cnt].push_back(x.v);bccno[x.v]=bcc_cnt;} if(x.u==u&&x.v==v) break; } } } else if(pre[v]
maxed) maxed=u; scanf("%d",&v); if(v>maxed) maxed=v; valid=true; u--,v--; G[u].push_back(v); G[v].push_back(u); } else {flag=false;break;} } if(!flag) break; if(valid==false) break; find_bcc(maxed); bool hascut=false; for(int i=0;i
?