對無向圖的三元環計數。
先對所有無向邊定向,從度數小的點連向度數大的點,度數相同時,從編號小的點連向編號大的點。枚舉每一個點 \(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)\)。