弦图总结

弦图

首先是弦的定义:

连接换上两个不相邻节点的边称为弦。

定义和数学中一个圆的弦比较像。
然后是弦图的定义:

若一张无向图中任意一个大小超过3的环都存在至少一条弦,那么这样的图称为弦图。

单纯点:

与其相邻的点集的诱导子图(把所以的边都连上后生成的图)是一个团(任两个点之间都有边)。

完美消除序列:

一个点的排列\(v_1,v_2...v_n\)满足\(v_i\)在${ v_i,v_{i+1}...v_n} $的诱导子图中为一个单纯点。

定理:一个无向图是弦图当且仅当它有一个完美消除序列。

用最大势算法\((Maximum\ Cardinality\ Search)\)可以在\(O(n+m)\)内求出一个消除序列的反序。
只要倒过来就可以了。

for (int i=n,now;i;--i)
{
	bool fg=0;
	while (!fg)
	{
		for (int j=v[best].size()-1;j>=0;--j)
			if (!vis[v[best][j]]) {fg=1;now=v[best][j];break;}
			else v[best].pop_back();
		if (!fg) --best;
	}
	seq[i]=now;rk[now]=i;vis[now]=1;
	for (int e=head[now];e;e=nxt[e])
		if (!vis[to[e]])
		{
			v[++label[to[e]]].push_back(to[e]);
			best=max(best,label[to[e]]);
		}
}

弦图的判定

朴素算法\(O(nm)=O(n^3)\)
优化算法:设\(\{ v_{i+1}...v_n \}\)中所有与\(v_i\)相邻的点依次为\(v_{j_1}...v_{j_k}\)
只需判断\(v_{j_1}\)是否与\(v_{j_2}...v_{j_k}\)相邻即可。
时间复杂度: \(O(n+m)=O(n^2)\)

for (int i=1;i<=n;++i)
{
	top=0;
	for (int e=head[seq[i]];e;e=nxt[e])
		if (rk[to[e]]<i) s[++top]=to[e];
	for (int j=2;j<=top;++j)
		if (!g[s[1]][s[j]]) ans=0;
}

最小色数问题

等于最小团数,也就是\(\max_{i=1}^{n}label[i]+1\)

最大独立集

等于最小团覆盖数。按照完美消除序列一个个贪心选取即可。




我目前就只会这么多,其他的就以后再补吧。
posted @ 2018-04-04 14:04  租酥雨  阅读(4948)  评论(2编辑  收藏