Loading

不会写波特·碧杨了😂

边双

没有桥的极大连通子图(\(u\)\(v\) 总有两条路径满足无边交),额外处理孤点

void tar(int now){
	dfn[now]=low[now]=++dfscnt;
	stk[++tp]=now;for(int v:vc[now]) if(v!=lst){
		if(!dfn[v]){
			tar(v);low[now]=min(low[now],low[v]);
			if(low[v]>dfn[now]){
                //(now,v)是桥
				++kcnt;do bel[stk[tp]].push_back(kcnt);while(stk[tp--]!=v);
			}
		}
		else low[now]=min(low[now],dfn[v]);
	}
}

点双

没有割点的极大连通子图(\(u\)\(v\) 总有两条路径满足除 \(u,v\) 两点外无点交),两点一边算作点双,仅割点属于多个,圆方树圆方相间额外处理孤点

void tar(int now){
	dfn[now]=low[now]=++dfscnt;
	stk[++tp]=now;for(int v:vc[now]){
		if(!dfn[v]){
			tar(v);low[now]=min(low[now],low[v]);
			if(low[v]>=dfn[now]){
				++kcnt;bel[now].push_back(kcnt);
				do bel[stk[tp]].push_back(kcnt);while(stk[tp--]!=v);
			}
		}
		else low[now]=min(low[now],dfn[v]);
	}
}

仙人掌上树

每个简单环(包括二元环)为点双,两点一边不算点双直接连,方方不相接,每个环抽出一个作为根连向方点,方点连向剩余结点,已经父->子定向,边权具体分析

void tar(int now,int lst){
	dfn[now]=low[now]=++dcnt;stk[++tp]=now;
	for(auto[v,w]:gp[now]) if(v!=lst){
		if(!dfn[v]){
			tar(v,now);low[now]=min(low[now],low[v]);
			if(low[v]>dfn[now]) vc[now].push_back((ed){v,w});
		}
		else if(dfn[v]<low[now]){
			low[now]=dfn[v];
			vc[v].push_back((ed){++fc,0});rt[fc]=v;
			for(int t=tp;stk[t]!=v;--t) vc[fc].push_back((ed){stk[t],0});
		}
	}--tp;
}

强连通分量

void tar(int now){
	dfn[now]=low[now]=++dfscnt;
	stk[++tp]=now;ist[now]=1;
	for(int v:vc[now]){
		if(!dfn[v]){
			tar(v);low[now]=min(low[now],low[v]);
		}
		else if(ist[v]) low[now]=min(low[now],dfn[v]);
	}
	if(dfn[now]==low[now]){
		++kcnt;do ist[stk[tp]]=0,bel[stk[tp]]=kcnt;while(stk[tp--]!=now);
	}
}
posted @ 2024-08-01 16:57  Albertvαn  阅读(4)  评论(0编辑  收藏  举报