其他分享
首页 > 其他分享> > 图

作者:互联网

\(\bold{Tarjan\ SCC}\)

OI-Wiki 里说的还好。

贴一个代码。

void Tarjan( int u ){
	idx[ u ] = low[ u ] = ++ c , s[ ++ t ] = u , ins[ u ] = 1 , pos[ u ] = t;
	for( int v : V[ u ] )
		if( ! idx[ v ] ) Tarjan( v ) , low[ u ] = min( low[ u ] , low[ v ] ); 
		else if( ins[ v ] ) low[ u ] = min( low[ u ] , idx[ v ] );
	if( low[ u ] == idx[ u ] ){
		++ scc;
		for( int i = pos[ u ] ; i <= t ; i ++ ) S[ s[ i ] ] = scc , siz[ scc ] ++ , ins[ s[ i ] ] = 0;
		t = pos[ u ] - 1;
	}
}
\(\bold{2-SAT}\)

一个关系是 \(u=x\Rightarrow v=y\ ,x,y\in[0,1]\) 这样的。

将元素和关系转化为有向图 \(G\),对一个元素对应两个顶点 \(u_1,u_0\) 表示 \(u=1\) 或 \(u=0\),一个关系 \(u=x\Rightarrow v=y\) 对应一条弧 \((u_x,v_y)\),易见图中一条路径 \(p(u_x,v_y)\) 意义为若 \(u=x\) 可以推出 \(v=y\)。

假若有一个元素 \(u\) 在图中对应的两个点互相可达即存在两条路径 \(p(u_0,u_1)\),\(p(u_1,u_0)\),则据路径意义,该元素无解。

两点互相可达即该两点强连通,于是我们考虑利用 \(\text{Tarjan}\) 求出 \(G\) 中所有的强连通分量,判断所有对应点是否在同一强连通分量即可。

时间复杂度 \(O(n+m)\)。

如果要构造方案的话,直接在 \(\text{Tarjan}\) 跑出的新 \(\text{DAG}\) 上拓扑排序一下

标签:,Tarjan,idx,int,text,++,low
来源: https://www.cnblogs.com/yukari1735/p/16463439.html