1. 程式人生 > >弦圖(Chordal Graph)學習小記

弦圖(Chordal Graph)學習小記

前言

這是個什麼神仙玩意兒?(仙圖 先把結論貼出來方便背板,證明什麼的啃完再補 考NOI前千萬不要點開什麼毒瘤的技能樹 所以現在點 由於很懶所以想到哪寫到哪

一些約定

GG無向圖 G[S]G[S]點集S的誘導子圖 δ(S)\delta(S)點集S的臨集

一些定義

連線環上不相鄰兩點之間的邊

弦圖

任意長度>=4的環都有至少一條弦的圖 這是弦圖,這不是弦圖.jpg

單純點

一個點v是單純點當且僅當G[δ(v)]+vG[\delta(v)]+v是團

完美消除序列

一個n的排列v1,v2,v3…vn,滿足vi在vi,vi+1,vi+2…vn的誘導子圖中是一個單純點

一些性質

弦圖的判定

一個圖是弦圖當且僅當其有完美消除序列

最大勢演算法(MCS)

每個點有一個標號label[v],初始label[v]=0 從後往前確定完美消除序列中的每一個元素,每次選擇label最大的點v加入序列,並將δ(v)\delta(v)中的點的label+1 具體實現可以開n個佇列,不需要刪除 複雜度O(n+m)

void MCS() {
    int mx=0;
    fo(i,0,n) lst[i+n+1]=0;
    fo(i,1,n) sz[i]=0,vis[i]=0,add(n+1,i);
    fd(j,n,1) {
        int p=0;
        for(++mx;!p;) {
            --mx;int Id=mx+n+1;
            while (int k=lst[Id]) {
                int x=t[k];
                lst[Id]=nxt[k];
                if (!vis[x]) {
                    vis[x]=1;
                    rep(i,x) {
                        int y=t[i];
                        if (!vis[y]) {
                            mx=max(mx,++sz[y]);
                            add(sz[y]+n+1,y);
                        }
                    }
                    p=x;
                    break;
                }
            }
        }
        seq[rk[p]=j]=p;
    }
}

弦圖的判定

bzoj1242 先跑一邊MCS,然後考慮判定每個點是不是單純點 直接暴力是O((∑deg)^2)的,設α(v)\alpha(v)表示v在完美消除序列中的排名,v1,v2…vk表示δ(v)\delta(v)α\alpha大於v的點按α\alpha排序之後的序列,那麼只需要判斷v1是否和v2…vk相鄰即可。

弦圖的極大團

N(v)=uuδ(v)α(u)>α(v)N(v)={u|u\in\delta(v)且\alpha(u)>\alpha(v)} 定理:弦圖中所有的團都滿足是v

N(v)v\cup N(v)的形式 如何判斷某一個vN(v)v\cup N(v)是不是極大團? 若存在u,令A=uN(u)A=u\cup N(u) B=vN(v)B=v\cup N(v),若BAB\subseteq AvN(v)v\cup N(v)不是極大團 顯然此時α(w)<α(v)\alpha(w)<\alpha(v)nxt[v]nxt[v]表示N(v)N(v)中最前的點,ww*表示所有滿足BAB\subseteq A的w的最後的一個點。 那麼此時有nxt[w]=vnxt[w*]=v 於是我們只需要判定所有nxt[w]=vnxt[w]=v的點w 判定的話只需要N(v)+1<=N(w)|N(v)|+1<=|N(w)|