P1989 无向图三元环计数
P1989 无向图三元环计数
我们强制给无向图的边定向。
那么考虑暴力枚举 \(a\) 和它可以到达的 \(b\) 再枚举 \(b\) 可以到达的 \(c\) ,同时要求 \(a\) 可以到 \(c\) 。就是 \((a\to b,b\to c,a\to c)\)。
我们强制令度数大的连向度数小的(度数一样比标号),发现这样时间复杂度是 \(O(m\sqrt m)\) (下方证明)。
考虑 \(deg\ge\sqrt m\) 的点,只有 \(\sqrt m\) 个点每个最多把所有边枚举一遍,时间复杂度 \(O(m)\)。
考虑 \(deg<\sqrt m\) 的点,显然遍历一遍 \(b\) 的出度是 \(O(\sqrt m)\) 的,而总度数是 \(O(m)\) 的。
综上,总的时间复杂度 \(O(m\sqrt m)\)。
//starusc
inline void addedge(int u,int v){
if(deg[u]<deg[v]||(deg[u]==deg[v]&&u<v))u^=v^=u^=v;
e[u].push_back(v);
}
int main(){
n=read();m=read();
for(int i=1;i<=m;i++){
uu[i]=read();vv[i]=read();
++deg[uu[i]];++deg[vv[i]];
}
for(int i=1;i<=m;i++)addedge(uu[i],vv[i]);
for(int i=1;i<=n;i++){
for(auto u:e[i])vis[u]=i;
for(auto u:e[i])
for(auto v:e[u])if(vis[v]==i)ans++;
}
cout<<ans<<"\n";
return (0-0);
}
作者:starusc
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号