无向图的连通性bz(双连通)桥
1、啥叫双连通,一个图,不存在割点,桥就是双连通。
这样的图有啥性质:从x到y一定存在至少两条不共边的路(可以共点)。
缩点是啥:把各各双连通的块划分成一个,产生一个新图(树,一定不成环)。
2、写法
1、先用tarjan求出来割边。
2、dfs给每一块双连通标号。
3、对于是桥的边,建一个新图,其中newx,newy分别为c[x],c[y]。不是割边的端点不进行操作。
//求割边 void tarjan(int x,int in_edge) { dfn[x] = low[x] = ++num; for(int i = head[x];i;i = nextt[i]){ int y = ver[i]; if(!dfn[y]){ tarjan(y,i); low[x] = min(low[x],low[y]); if(low[y] > dfn[x]) bridge[i] = bridge[i^1] = 1; //que.push(make_pair(min(i,i^1),max(i,i^1))); } else if(i!=(in_edge^1)) low[x] = min(low[x],dfn[y]); } } //给每一块标号 int c[maxn],dcc; void dfs(int x) { c[x] = dcc; for(int i = head[x];i;i = nextt[i]){ int y = ver[i]; if(c[y] || bridge[i]) continue; dfs(y); } } //main main tot = 1; for(int i = 1;i <= m;++i){ int x,y; cin>>x>>y; add(x,y);add(y,x); } for(int i = 1;i <= n;++i){ if(!dfn[i]) tarjan(i,0); } for(int i = 1;i <= n;++i){ if(!c[i]){ ++dcc; dfs(i); } } totc = 0; for(int i = 2; i <= tot;i = i+2){ int x = ver[i],y = ver[i^1]; if(c[x] == c[y]) continue; //cout<<c[x]<<sp<<c[y]<<endl; addc(c[y],c[x]); addc(c[x],c[y]); }

浙公网安备 33010602011771号