求去掉每一个割点后剩下几个连通分量
就求割点那个算法 里面加点东西就行
cnt[i]代表如果i是割点 去掉后会有几个连通分量
根节点要有2个或以上的的子树才是割点 根是割点 那么cnt[root] = child(子树的个数)不是割点cnt[root] = 0;
#include <cstdio> #include <cstring> #include <vector> #include <stack> #include <algorithm> using namespace std; const int maxn = 1010; vector <int> a[maxn], bcc[maxn]; int pre[maxn]; int low[maxn]; bool iscut[maxn]; int bccno[maxn]; int cnt[maxn]; int dfs_clock; int bcc_cnt; int n; struct Edge { int u, v; }; stack <Edge> S; int dfs(int u, int fa) { int lowu = pre[u] = ++dfs_clock; int child = 0; for(int i = 0; i < a[u].size(); i++) { int v = a[u][i]; Edge e = (Edge){u, v}; if(!pre[v]) { S.push(e); child++; int lowv = dfs(v, u); lowu = min(lowu, lowv); if(lowv >= pre[u]) { iscut[u] = true; bcc_cnt++; bcc[bcc_cnt].clear(); cnt[u]++; while(1) { 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] < pre[u] && v != fa) { S.push(e); lowu = min(lowu, pre[v]); } } if(fa < 0 && child == 1) { iscut[u] = false; cnt[u] = 0; } if(fa < 0 && child > 1) { iscut[u] = true; cnt[u] = child; } else if(cnt[u] > 0) cnt[u]++; return lowu; } void find_bcc() { memset(cnt, 0, sizeof(cnt)); memset(pre, 0, sizeof(pre)); memset(iscut, 0, sizeof(iscut)); memset(bccno, 0, sizeof(bccno)); dfs_clock = bcc_cnt = 0; dfs(1, -1); } int main() { int u, v; int cas = 0; while(scanf("%d", &u) && u) { scanf("%d", &v); n = 0; n = max(n, u); n = max(n, v); for(int i = 1; i <= 1000; i++) a[i].clear(); a[u].push_back(v); a[v].push_back(u); while(scanf("%d", &u) && u) { scanf("%d", &v); a[u].push_back(v); a[v].push_back(u); n = max(n, u); n = max(n, v); } find_bcc(); if(cas++) puts(""); printf("Network #%d\n", cas); int flag = 0; for(int i = 1; i <= n; i++) { if(iscut[i]) { printf(" SPF node %d leaves %d subnets\n", i, cnt[i]); flag++; } } if(!flag) printf(" No SPF nodes\n"); //printf("\n"); } return 0; }