1. 程式人生 > 實用技巧 >三元環

三元環

對無向圖的三元環計數。

先對所有無向邊定向,從度數小的點連向度數大的點,度數相同時,從編號小的點連向編號大的點。列舉每一個點 \(x\),將其連出的點 \(y\) 都打上 \(x\) 的標記,再列舉點 \(y\) 連出的點 \(z\),若點 \(z\)\(x\) 的標記,則 \((x,y,z)\) 為一個三元環。

這樣每個三元環只會在 \(x\) 處統計一次。

for(int i=1;i<=m;++i)
{
    int x=ed[i].x,y=ed[i].y;
    if(deg[x]>deg[y]||(deg[x]==deg[y]&&x>y)) swap(x,y);
    add(x,y);
}
for(int x=1;x<=n;++x)
{
    for(int i=head[x];i;i=e[i].nxt) vis[e[i].to]=x;
    for(int i=head[x];i;i=e[i].nxt)
        for(int j=head[e[i].to];j;j=e[j].nxt)
            if(vis[e[j].to]==x)
                ans++;
}

定向後的圖是不存在環的,因為如果存在環,則環上的每個點度數都相同,且編號都相同,這樣的情況是不存在的。

列舉的過程中,\(x \longrightarrow y\) 這條邊對複雜度的貢獻為 \(y\) 的出邊個數 \(out_y\),得總貢獻為 \(\sum\limits_{i=1}^m out_{y_i}\)

\(deg_y \leqslant \sqrt m\) 時,得 \(out_y\)\(O(\sqrt m)\) 的。

\(deg_y > \sqrt m\) 時,因為度數和是 \(O(m)\) 的,度數大於 \(deg_y\) 的點的個數是 \(O(\sqrt m)\)

的,得 \(out_y\)\(O(\sqrt m)\) 的。

所以複雜度為 \(O(m \sqrt m)\)