题意:
问你这个图中哪个点是割点,如果把这个点去掉会有几个子网
代码:
1 //给你几个点,用着几个点形成了一个图。输入边形成的图,问你这个图中有多少个割点。每一个割点去掉后会形成几个强连通分量
2 //方法:
3 //你可以想用tarjan算法求出来谁是割点。然后每一个割点单独用并查集判断。用所有边(不和这个割点相连的边)通过并查集判断一下
4 //然合并后有几个区域就可以了
5 #include<stdio.h>
6 #include<string.h>
7 #include<algorithm>
8 using namespace std;
9 const int spot=1010;
10 const int edge=500010;
11 struct node
12 {
13 int u,v;
14 }m[edge];
15 struct stu
16 {
17 int to,next;
18 } a[edge];
19 int head[spot],fa,low[spot],num[spot],root,indexx,sizes,flag1,n,fx[spot],qua,len,v[spot]; //fx指祖节点
20 bool flag[spot],flag2[spot],b[spot],have[spot];
21 void init()
22 {
23 indexx=0,sizes=0,flag1=1,n=0;
24 len=qua=0;
25 memset(head,-1,sizeof(head));
26 memset(low,0,sizeof(low));
27 memset(num,0,sizeof(num));
28 memset(flag,0,sizeof(flag));
29 memset(have,0,sizeof(have));
30 }
31 void add_edge(int from,int to) //并查集
32 {
33 a[sizes].to=to;
34 a[sizes].next=head[from];
35 head[from]=sizes++;
36 a[sizes].to=from;
37 a[sizes].next=head[to];
38 head[to]=sizes++;
39 n=max(n,from);
40 n=max(n,to);
41 m[len].u=from;
42 m[len++].v=to;
43 }
44 void dfs(int cur) //求割点
45 {
46 int child=0;
47 num[cur]=++indexx;
48 low[cur]=indexx;
49 int k,v;
50 for(k=head[cur]; k+1; k=a[k].next)
51 {
52 v=a[k].to;
53 if(!num[v])
54 {
55 dfs(v);
56 low[cur]=min(low[cur],low[v]);
57 if(low[v]>=num[cur])
58 {
59 child++;
60 if(cur!=fa || child>1) flag[cur]=1,qua++;
61 }
62 }
63 else
64 low[cur]=min(low[cur],num[v]);
65 }
66 }
67 int finds(int x)
68 {
69 if(x!=v[x])
70 {
71 int y=finds(v[x]);
72 return v[x]=y;
73 }
74 return x;
75 }
76 int panduan(int x)
77 {
78 for(int i=1;i<=n;++i)
79 {
80 if(have[i]) v[i]=i;
81 }
82 for(int i=0;i<len;++i)
83 {
84 if(m[i].u!=x && m[i].v!=x)
85 {
86 int fx=finds(m[i].u);
87 int fy=finds(m[i].v);
88 if(fx!=fy) v[fx]=fy;
89 }
90 }
91 int ans=0;
92 for(int i=1;i<=n;++i)
93 {
94 if(i!=x && v[i]==i) ++ans;
95 }
96 return ans;
97 }
98 int main()
99 {
100 int x,y,i,ss=0,ans,j;
101 while(scanf("%d",&x)&&x)
102 {
103 init();
104 scanf("%d",&y);
105 root=x;
106 have[x]=1;
107 have[y]=1;
108 add_edge(x,y);
109 for(;;)
110 {
111 scanf("%d",&x);
112 if(!x) break;
113 scanf("%d",&y);
114 add_edge(x,y);
115 have[x]=1,have[y]=1;
116 }
117 fa=root;
118 dfs(root);
119 printf("Network #%d\n",++ss);
120 for(i=1; i<=n; i++)
121 {
122 if(flag[i])
123 {
124 flag1=0;
125 int q=panduan(i);
126 printf(" SPF node %d leaves %d subnets\n",i,q);
127 }
128 }
129 if(flag1)
130 printf(" No SPF nodes\n");
131 printf("\n");
132 }
133 return 0;
134 }