• 弦图总结


    弦图

    首先是弦的定义:

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

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

    若一张无向图中任意一个大小超过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)

    最大独立集

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




    我目前就只会这么多,其他的就以后再补吧。
  • 相关阅读:
    poj 3636
    poj 1065 Wooden Sticks
    2017北京国庆刷题Day6 afternoon
    2017北京国庆刷题Day5 afternoon
    2017北京国庆刷题Day3 afternoon
    2017北京国庆刷题Day3 morning
    2017北京国庆刷题Day2 afternoon
    2017北京国庆刷题Day2 morning
    poj2420 A Star not a Tree?
    NOIP2016 愤怒的小鸟
  • 原文地址:https://www.cnblogs.com/zhoushuyu/p/8716935.html
Copyright © 2020-2023  润新知