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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

三元环讲解

發布時間:2023/12/3 编程问答 47 豆豆
生活随笔 收集整理的這篇文章主要介紹了 三元环讲解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考文章:
不常用的黑科技——「三元環」

引入

給定一張無重邊,無自環的無向圖,點數為n,邊數為m,且n,m同階,問有多少個無序三元組(i,j,k),使得存在:

  • 有一個連接i,j的邊
  • 有一條連接j,k的邊
  • 有一條鏈接k,i的邊
    即三元環
  • 解決方法:

    首先對所有的無向圖進行定向,對于任意一條邊,從度數大的點連向度數小的點,當度數一樣時,從編號小的點連向編號大的點

    此時就得到一個有向無環圖

    然后枚舉每一個點,將u所有到達的點v進行標記,標記為u,然后再遍歷點v,枚舉點v所能到達的點w,如果w存在被u訪問的標記,則說明(u,v,w)是一個三元環

    證明:

    這里講的很詳細,我就不做贅述
    不常用的黑科技——「三元環」

    復雜度

    O(n+m+nm+mm)=O(mm)O(n+m+n\sqrt{m}+m\sqrt{m})=O(m\sqrt{m})O(n+m+nm?+mm?)=O(mm?)

    代碼:

    #include <bits/stdc++.h> using namespace std; const int N = 1e5 + 10; vector<int> g[N]; int deg[N], vis[N], n, m, ans; struct E { int u, v; } e[N * 3]; int main() {scanf("%d%d", &n, &m);for(int i = 1 ; i <= m ; ++ i) {scanf("%d%d", &e[i].u, &e[i].v);++ deg[e[i].u], ++ deg[e[i].v];}for(int i = 1 ; i <= m ; ++ i) {int u = e[i].u, v = e[i].v;if(deg[u] < deg[v] || (deg[u] == deg[v] && u > v)) swap(u, v);g[u].push_back(v);}for(int x = 1 ; x <= n ; ++ x) {for(auto y: g[x]) vis[y] = x;for(auto y: g[x])for(auto z: g[y])if(vis[z] == x)++ ans;}printf("%d\n", ans); }

    總結

    以上是生活随笔為你收集整理的三元环讲解的全部內容,希望文章能夠幫你解決所遇到的問題。

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