题意:
有一张联通网络,求出所有的割点;
对于割点 u ,求将 u 删去后,此图有多少个联通子网络;
对于含有割点的,按升序输出;
题解:
DFS求割点入门题,不会的戳这里?求无向连通图的割点
AC代码:
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 using namespace std; 5 #define mem(a,b) memset(a,b,sizeof(a)) 6 const int maxn=1e3+50; 7 8 int num; 9 int fa[maxn]; 10 int dfn[maxn]; 11 int low[maxn]; 12 bool vis[maxn]; 13 bool son[maxn]; 14 int artPoint[maxn]; 15 int head[maxn]; 16 struct Edge 17 { 18 int to; 19 int next; 20 }G[1000010]; 21 void addEdge(int u,int v) 22 { 23 G[num].to=v; 24 G[num].next=head[u]; 25 head[u]=num++; 26 } 27 void DFS(int u,int f,int &k) 28 { 29 if(f == 1 && !son[u]) 30 artPoint[1]++;//求根节点的子树分支个数 31 32 fa[u]=f; 33 vis[u]=true; 34 dfn[u]=low[u]=++k; 35 for(int i=head[u];~i;i=G[i].next) 36 { 37 int v=G[i].to; 38 if(!vis[v]) 39 { 40 DFS(v,u,k); 41 42 if(u != 1 && low[v] >= dfn[u]) 43 artPoint[u]++; 44 low[u]=min(low[u],low[v]); 45 } 46 else if(fa[u] != v) 47 low[u]=min(dfn[v],low[u]); 48 } 49 } 50 void Solve() 51 { 52 int k=0; 53 DFS(1,-1,k); 54 int ans=0; 55 for(int i=1;i <= 1000;++i) 56 { 57 //特判根节点 58 if(i == 1 && artPoint[1] <= 1) 59 continue; 60 61 //对于割点i,artPoint[i]:将其删去后,其儿子所形成的联通子图个数 62 //+1:加上其父亲的联通子图 63 if(artPoint[i] > 0) 64 { 65 ans++; 66 printf(" SPF node %d leaves %d subnets\n",i,artPoint[i]+(i != 1)); 67 } 68 } 69 if(ans == 0) 70 printf(" No SPF nodes\n"); 71 } 72 void Init() 73 { 74 num=0; 75 mem(head,-1); 76 mem(vis,false); 77 mem(artPoint,0); 78 } 79 int main() 80 { 81 //freopen("C:/Users/hyacinthLJP/Desktop/stdin/contest","r",stdin); 82 int u,v; 83 int kase=1; 84 bool flag=false; 85 while(~scanf("%d",&u) && u) 86 { 87 Init(); 88 scanf("%d",&v); 89 addEdge(u,v); 90 addEdge(v,u); 91 while(~scanf("%d",&u) && u) 92 { 93 scanf("%d",&v); 94 addEdge(u,v); 95 addEdge(v,u); 96 } 97 if(flag) 98 printf("\n"); 99 flag=true; 100 101 printf("Network #%d\n",kase++); 102 Solve(); 103 } 104 105 return 0; 106 }