日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

aop判断方法是否执行成功_判断图中是否有环的三种方法

發(fā)布時間:2025/3/12 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 aop判断方法是否执行成功_判断图中是否有环的三种方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

0、什么是環(huán)?

在圖論中,環(huán)(英語:cycle)是一條只有第一個和最后一個頂點重復的非空路徑。

在有向圖中,一個結點經過兩種路線到達另一個結點,未必形成環(huán)。

1、拓撲排序

1.1、無向圖

使用拓撲排序可以判斷一個無向圖中是否存在環(huán),具體步驟如下:

  • 求出圖中所有結點的度。
  • 將所有度 <= 1 的結點入隊。(獨立結點的度為 0)
  • 當隊列不空時,彈出隊首元素,把與隊首元素相鄰節(jié)點的度減一。如果相鄰節(jié)點的度變?yōu)橐?#xff0c;則將相鄰結點入隊。
  • 循環(huán)結束時判斷已經訪問的結點數是否等于 n。等于 n 說明全部結點都被訪問過,無環(huán);反之,則有環(huán)。
  • 1.2、有向圖

    使用拓撲排序判斷無向圖和有向圖中是否存在環(huán)的區(qū)別在于:

    • 在判斷無向圖中是否存在環(huán)時,是將所有**度 <= 1** 的結點入隊;
    • 在判斷有向圖中是否存在環(huán)時,是將所有**入度 = 0** 的結點入隊。(感謝 wangweijun@shen 指正!!!)

    2、DFS

    使用 DFS 可以判斷一個無向圖和有向中是否存在環(huán)。深度優(yōu)先遍歷圖,如果在遍歷的過程中,發(fā)現某個結點有一條邊指向已訪問過的結點,并且這個已訪問過的結點不是上一步訪問的結點,則表示存在環(huán)。

    我們不能僅僅使用一個 bool 數組來表示結點是否訪問過。規(guī)定每個結點都擁有三種狀態(tài),白、灰、黑。開始時所有結點都是白色,當訪問過某個結點后,該結點變?yōu)榛疑?#xff0c;當該結點的所有鄰接點都訪問完,該節(jié)點變?yōu)楹谏?/p>

    那么我們的算法可以表示為:如果在遍歷的過程中,發(fā)現某個結點有一條邊指向灰色節(jié)點,并且這個灰色結點不是上一步訪問的結點,那么存在環(huán)。

    #include <iostream> #include <queue> #include <vector> using namespace std;vector<vector<int>> g; vector<int> color; int last; bool hasCycle;bool topo_sort() {int n = g.size();vector<int> degree(n, 0);queue<int> q;for (int i = 0; i < n; i++) {degree[i] = g[i].size();if (degree[i] <= 1) {q.push(i);}}int cnt = 0;while (!q.empty()) {cnt++;int root = q.front();q.pop();for (auto child : g[root]) {degree[child]--;if (degree[child] == 1) {q.push(child);}}}return (cnt != n); }void dfs(int root) {color[root] = 1;for (auto child : g[root]) {if (color[child] == 1 && child != last) {hasCycle = true;break;}else if (color[child] == 0) {last = root;dfs(child);}}color[root] = 2; }int main() {int n = 4;g = vector<vector<int>>(n, vector<int>());g[0].push_back(1);g[1].push_back(0);g[1].push_back(2);g[2].push_back(1);g[2].push_back(3);g[3].push_back(2);cout << topo_sort() << endl; //0,無環(huán)color = vector<int>(n, 0);last = -1;hasCycle = false;dfs(0);cout << hasCycle << endl; //0,無環(huán)g[0].push_back(3);g[3].push_back(0);cout << topo_sort() << endl; //1,有環(huán)color = vector<int>(n, 0);last = -1;hasCycle = false;dfs(0);cout << hasCycle << endl; //1,有環(huán)return 0; }

    3、Union-Find Set

    我們可以使用并查集來判斷一個圖中是否存在環(huán):

    對于無向圖來說,在遍歷邊(u-v)時,如果結點 u 和結點 v 的“父親”相同,那么結點 u 和結點 v 在同一個環(huán)中。

    對于有向圖來說,在遍歷邊(u->v)時,如果結點 u 的“父親”是結點 v,那么結點 u 和結點 v 在同一個環(huán)中。

    #include <algorithm> #include <iostream> #include <vector> using namespace std;vector<pair<int, int>> g; vector<int> father;int findFather(int x) {int a = x;while (x != father[x]) {x = father[x];}while (a != father[a]) {int z = a;a = father[a];father[z] = x;}return x; }void Union(int a, int b) {int fa = findFather(a);int fb = findFather(b);father[a] = father[b] = min(fa, fb); }bool isCyclicUnirectedGraph() {for (int i = 0; i < g.size(); i++) {int u = g[i].first;int v = g[i].second;if (father[u] == father[v]) {return true;}Union(u, v);}return false; }bool isCyclicDirectedGraph() {for (int i = 0; i < g.size(); i++) {int u = g[i].first;int v = g[i].second;if (father[u] == v) {return true;}father[v] = findFather(u);}return false; }int main() {// Undirected acyclic graph// 0// / // 1 2g.push_back(make_pair(0, 1));g.push_back(make_pair(0, 2));for (int i = 0; i < 3; i++) {father.push_back(i);}cout << isCyclicUnirectedGraph() << endl; //0,無環(huán)// Undirected cyclic graph// 0// / // 1———2g.push_back(make_pair(1, 2));vector<int>().swap(father);for (int i = 0; i < 3; i++) {father.push_back(i);}cout << isCyclicUnirectedGraph() << endl; //1,有環(huán)// Directed acyclic graph// 0// / // v v// 1——>2vector<pair<int, int>>().swap(g);g.push_back(make_pair(0, 1));g.push_back(make_pair(1, 2));g.push_back(make_pair(0, 2));vector<int>().swap(father);for (int i = 0; i < 3; i++) {father.push_back(i);}cout << isCyclicDirectedGraph() << endl; //0,無環(huán)// Directed cyclic graph// 0// / ^// v // 1——>2g.pop_back();g.push_back(make_pair(2, 0));vector<int>().swap(father);for (int i = 0; i < 3; i++) {father.push_back(i);}cout << isCyclicDirectedGraph() << endl; //1,有環(huán)return 0; }

    References

  • 環(huán) (圖論)
  • 有向無環(huán)圖
  • 判斷一個圖是否有環(huán)及相關 LeetCode 題目
  • 判斷有向圖是否存在環(huán)的 2 種方法(深度遍歷,拓撲排序)
  • 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的aop判断方法是否执行成功_判断图中是否有环的三种方法的全部內容,希望文章能夠幫你解決所遇到的問題。

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