不常用的黑科技——「三元環」
好的證明複雜度是:
對於度數大於根號的點,最多根號個。稱為大點。
度數小於根號的點,稱為小點。
對於小點,邊怎麼定向不關心。之後度數最多根號個
對於大點,和小點的邊一定是被小點指過來,只可能保留指向大點的出邊。之後度數最多根號個。
複雜度本質是考慮每個點會被二次列舉多少次。也就是入邊個數。
入邊個數總共是m,每個點度數小於根號m
所以總複雜度是msqrt(m)
挺暴力的做法,
依靠對三元環無向邊的定向,使得暴力列舉的複雜度其實是o(msqrt(m))
一些挺複雜的圖的東西有時候可以根據度數分塊考慮來優化暴力
但是這個做法巧妙之處按照度數定向,是可以通過度數的大小證明複雜度。。
例題:pa2009 cakes
#include#define reg register int#define il inline
#define numb (ch^'0')
using
namespace
std;
typedef
long
long
ll;il
void rd(int &x)
namespace
miraclee[
250000+5
];int
hd[n],cnt;
void add(int x,int
y)int
du[n];
int b[250000+5][2
];ll ans=0
;int
vis[n];
intmain()
for(reg i=1;i<=m;++i)
for(reg x=1;x<=n;++x)
for(reg i=hd[x];i;i=e[i].nxt)}}
printf(
"%lld
",ans);
return0;
}}signed main()
/*author: *miracle*
date: 2019/3/6 14:12:52
*/
bzoj5407 girls
大力容斥
[sdoi2018]舊試題
附疑問:
有向圖三元環計數比較好的做法?
不知。(可以bitset)
有時候,在dag列舉路徑轉移的時候,重新定向可以暴力列舉前驅或者後繼,複雜度就有了保證
upda:2019.5.6
四元環計數?一共有三種情況
本做法不用分類討論.
給每個點分配乙個rank ,rki
建立新邊,rk小的連向rk大的
顯然是dag
乙個環有三種情況
列舉u,走原邊到v,再走新邊到w,如果rk(u)
cnt每次列舉u完了之後要清空.
三種情況都會恰好被計算一次
三元環 四元環計數
這東西其實就是一種暴力,只不過巧妙的是每乙個環恰好統計了一次。三元環計數推薦一篇部落格,科技 三元環計數,很詳細,很清楚。每乙個三元環之所以被算了一次,是因為乙個三元環在新圖上必定只有乙個點的出度為2,然後我們只在這個點上更新三元環數量。然後我放了個 define fore i,x,y for in...
三元環計數
也許更好的閱讀體驗 給一張 n 個點,m 條邊的簡單無向圖,求解有多少個三元環 三元環 乙個三元組 left i,j,k right 表示三個點,要求存在邊 left i,j right left i,k right left j,k right 我們先把每個點 i 定義乙個雙關鍵字 left de...
三元環計數
參考部落格 洛谷模板 無向圖三元環計數 將無向圖轉化成有向圖,度大的指向度小的,若度一樣,按照編號排序。列舉每個點x,將x的所有相鄰點標記,然後列舉x的相鄰點y,再列舉y的相鄰點z,如果z已經被標記,那麼 x,y,z 就是如圖示的三元環。複雜度 o n sqrt n includeusing nam...