SPF
题意:无向图,求割顶以及去掉该割顶后有几个连通分量。
去掉一个割顶后,从割顶dfs遍历整张图,每扫一个连通分量计数器加1

1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 using namespace std; 5 const int maxv=1010; 6 int n; 7 struct Edge{ 8 int v,nex; 9 }e[maxv*maxv<<1]; 10 int head[maxv]; 11 int cnt=0; 12 void init(){ 13 memset(head,-1,sizeof(head)); 14 cnt=0; 15 n=0; 16 } 17 void add(int u,int v){ 18 e[cnt].v=v; 19 e[cnt].nex=head[u]; 20 head[u]=cnt++; 21 } 22 23 int pre[maxv],iscut[maxv],dfsk; 24 25 int dfs(int u,int id){ 26 int lowu=pre[u]=++dfsk; 27 int child=0; 28 for(int i=head[u];i!=-1;i=e[i].nex){ 29 if(i==(id^1)) continue; 30 int v=e[i].v; 31 if(!pre[v]){ 32 child++; 33 int lowv=dfs(v,i); 34 lowu=min(lowu,lowv); 35 if(lowv>=pre[u]) iscut[u]=1; 36 } 37 else if(pre[v]<pre[u]) lowu=min(lowu,pre[v]); 38 } 39 if(id<0&&child==1) iscut[u]=0; //注意!!! 40 return lowu; 41 } 42 void find_bcc(int n){ 43 memset(pre,0,sizeof(pre)); 44 memset(iscut,0,sizeof(iscut)); 45 dfsk=0; 46 for(int i=0;i<n;i++) if(!pre[i]) dfs(i,-1); 47 } 48 int vis[maxv],bct=0; 49 void check(int u,int f){ 50 vis[u]=1; 51 for(int i=head[u];i!=-1;i=e[i].nex){ 52 int v=e[i].v; 53 if(!vis[v]){ 54 if(u==f) bct++; 55 check(v,f); 56 } 57 } 58 } 59 int main(){ 60 int u,v; 61 int kase=0; 62 init(); 63 while(scanf("%d",&u)!=EOF){ 64 if(u){ 65 scanf("%d",&v); 66 u--;v--; 67 n=max(n,max(u,v)); 68 add(u,v); 69 add(v,u); 70 }else { 71 if(cnt==0) break; 72 printf("Network #%d ",++kase); 73 find_bcc(n); 74 bool ok=0; 75 for(int i=0;i<n;i++) if(iscut[i]){ 76 ok=1; 77 bct=0; 78 memset(vis,0,sizeof(vis)); 79 check(i,i); 80 printf(" SPF node %d leaves %d subnets ",i+1,bct); 81 } 82 if(!ok) puts(" No SPF nodes"); 83 init(); 84 puts(""); 85 } 86 } 87 return 0; 88 }