弦圖
首先是弦的定義:
連接換上兩個不相鄰節點的邊稱為弦。
定義和數學中一個圓的弦比較像。
然后是弦圖的定義:
若一張無向圖中任意一個大小超過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\)
最大獨立集
等於最小團覆蓋數。按照完美消除序列一個個貪心選取即可。
我目前就只會這么多,其他的就以后再補吧。