日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

HDU6184【Counting Stars】(三元环计数)

發布時間:2023/12/15 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU6184【Counting Stars】(三元环计数) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題面

傳送門

給出一張無向圖,求 \(4\) 個點構成兩個有公共邊的三元環的方案數。

題解

orz余奶奶,orz zzk

首先,如果我們知道經過每條邊的三元環個數\(cnt_i\),那么答案就是\(\sum_{i=1}^m{cnt_i\choose 2}\)

所以現在問題就是該怎么數三元環

據說有一個設閾值的\(O(m\sqrt{m})\)的做法,不過常數太大了,這里不講

我們把每一條邊重定向,設它連接的兩個點的度數分別為\(deg_u\)\(deg_v\),那么把這條邊定為從度數大的連向度數小的,如果度數相同按標號大小。這樣顯然可以建出一個有向無環圖

所以怎么找環呢

我們枚舉點\(u\),并枚舉它的所有出邊,把出邊指向的點\(v\)標記上\(u\)。然后再枚舉一邊出邊,并對每個\(v\)也枚舉出邊,如果\(v\)的出邊指向的點\(w\)上的標記是\(u\)那么說明找到了一個三元環

顯然,每個三元環都會被統計恰好一次

接下來的問題是復雜度,我們要證明它的上界是\(O(m\sqrt{m})\)

1.\(\forall v,out_v\leq \sqrt{m}\),每一次枚舉\(v\)的出邊的復雜度不會超過\(O(\sqrt{m})\),所以這一部分復雜度不會超過\(O(m\sqrt{m})\)

2.\(\forall v,out_v\geq \sqrt{m}\),因為在這種情況下必有\(deg_u\geq deg_v\),所以所有這樣的\(u\)不會超過\(O(\sqrt{m})\)個,每一個\(out_v\)的貢獻最多是\(\sqrt{m}out_v\),由于\(\sum out_v=O(m)\),所以這一部分的復雜度也不會超過\(O(m\sqrt{m})\)

不過這個做法常數不知道比設閾值小到哪里去了

//minamoto #include<bits/stdc++.h> #define R register #define ll long long #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i) #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i) #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v) using namespace std; char buf[1<<21],*p1=buf,*p2=buf; inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;} int read(){R int res,f=1;R char ch;while((ch=getc())>'9'||ch<'0')if(ch==EOF)return -1;for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');return res*f; } const int N=2e5+5; struct eg{int v,nx;}e[N<<1];int head[N],tot; inline void add(R int u,R int v){e[++tot]={v,head[u]},head[u]=tot;} struct EG{int u,v;}E[N]; int n,m,tim,deg[N],pt[N],vis[N],cnt[N];ll res; int main(){ // freopen("testdata.in","r",stdin);while(~(n=read(),m=read())){tot=tim=0;fp(i,1,n)head[i]=deg[i]=vis[i]=0;fp(i,1,m)E[i].u=read(),E[i].v=read(),++deg[E[i].u],++deg[E[i].v],cnt[i]=0;fp(i,1,m)deg[E[i].u]>deg[E[i].v]||(deg[E[i].u]==deg[E[i].v]&&E[i].u>E[i].v)?add(E[i].u,E[i].v):add(E[i].v,E[i].u);fp(u,1,n){++tim;go(u)pt[v]=i,vis[v]=tim;for(R int k=head[u];k;k=e[k].nx)go(e[k].v)if(vis[v]==tim)++cnt[i],++cnt[k],++cnt[pt[v]];}res=0;fp(i,1,m)res+=1ll*cnt[i]*(cnt[i]-1)>>1;printf("%lld\n",res);}return 0; }

轉載于:https://www.cnblogs.com/bztMinamoto/p/10582360.html

總結

以上是生活随笔為你收集整理的HDU6184【Counting Stars】(三元环计数)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。