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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

DFS判断回路及回路个数

發布時間:2023/12/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 DFS判断回路及回路个数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

DFS判斷回路,僅需一個棧保存每一次的路徑,然后判斷該路徑是否存在回路即可,具體看代碼即可

#include"Graph.h" #include<iostream> #include<vector>void __topSort_DFS(Graph & G, int u, vector<int> & visited, short & cycleNum, stack<int> path ) {visited[u] = true;path.push(u); // 將當前結點加入路徑// 遍歷u每一個鄰接點vfor(int v = G.FirstNeighbor(u); v >= 0 ;v = G.NextNeighbor(u, v)) { if(!visited[v])__topSort_DFS(G, v, visited, cycleNum, path);// 對于已訪問過的鄰接點,需要判斷其是否構成回路(當然,path需要至少3個結點才能構成回路)elseif(path.size() >= 3 ){// 如果邊u->v指向路徑上的一個結點(路徑上的結點都是已訪問結點),說明存在一條回路// path.size()-2的目的就是排除路徑中最近的兩個結點:結點u自身和結點u的前驅結點,因為這兩種情況不能形成回路for(int i = 0;i < path.size()-2;++i) {if(topSeq[i] == v)cycleNum++;}}}path.pop(); // 當遍歷一條路徑到盡頭時,便會隨著路徑進行回溯,于是將當前結點出棧以回溯 } // 使用DFS判斷回路 void topSort_DFS(Graph & G) {vector<int> visited(G.vexNum, false);stack<int> path; // 存放DFS每一次可能的路徑short cycleNum = 0; // 可記錄圖中存在的回路數量// 遍歷所有的連通分量for(int u = 0; u < G.vexNum ; ++u) {if(!visited[u]) {cycleNum = false; // 對于每一個連通分量都判斷回路__topSort_DFS(G, u, visited, cycleNum, path);}}cout << "回路個數為:" << cycleNum << endl; }void fun1() {GraphAM G;G.vexNum = 5;G.edge[0][1] = 1;G.edge[1][3] = 1;G.edge[2][3] = 1;G.edge[2][4] = 1;G.edge[3][4] = 1;G.edge[4][2] = 1;G.edge[2][1] = 1;G.edge[2][0] = 1;topSort_DFS(G); }void fun2() {GraphAL G;G.vexNum = 5;G.adj[0].push_back({1, 1});G.adj[1].push_back({3, 1});G.adj[2].push_back({3, 1});G.adj[2].push_back({4, 1});G.adj[3].push_back({4, 1});G.adj[4].push_back({2, 1});G.adj[2].push_back({1, 1});G.adj[2].push_back({0, 1});topSort_DFS(G); }int main() {fun1();fun2();return 0; }

Graph.h:

#include<iostream> #include<vector>using namespace std;// 圖——抽象數據結構 struct Graph { public:static const int MAXVERTEX;static const int INF;int vexNum; // 頂點數int arcNum; // 邊數virtual int FirstNeighbor(int u) = 0; // 尋找點u的第一個鄰接點virtual int NextNeighbor(int u, int v) = 0; // 尋找處于鄰接點v的下一個兄弟鄰接點(都是u的鄰接點)virtual bool HasEdge(int u, int v) = 0; // 是否有邊(u->v)virtual int GetEdgeValue(int u, int v) = 0; // 獲取邊(u->v)的權重virtual vector<int> GetInDegree() = 0; // 得到該圖的入度表}; const int Graph::INF = 0xffffff; const int Graph::MAXVERTEX = 100;// 圖——鄰接矩陣表示 struct GraphAM: public Graph {int edge[MAXVERTEX][MAXVERTEX]; // 存放邊權重GraphAM() {for(int i = 0; i < MAXVERTEX ;++i)for(int j = 0; j < MAXVERTEX ;++j)edge[i][j] = INF;}int FirstNeighbor(int u) override {for(int i = 0;i < this->vexNum;i++)if(this->edge[u][i] != INF)return i;return -1;}int NextNeighbor(int u, int v) override {for(int i = v+1; i < this->vexNum ;i++)if(this->edge[u][i] != INF)return i;return -1;}bool HasEdge (int u, int v) override { return edge[u][v] != INF; }int GetEdgeValue(int u, int v) override { return edge[u][v]; }vector<int> GetInDegree() override {vector<int> inDegree(vexNum);for(int j = 0; j < vexNum ;++j) {for(int i = 0; i < vexNum ;++i) {if( edge[i][j] != INF ) {inDegree[j]++;}}}return inDegree;} };// 圖——鄰接表表示 struct GraphAL: public Graph {// 弧信息struct ArcNode {int v; // 表弧頭,即u->v 中的vint data;};vector<ArcNode> adj[MAXVERTEX]; // 鄰接表,adj[u][i]存儲了u的第i個鄰接邊的信息GraphAL() {}int FirstNeighbor(int u) override {// cout << "FirstNeighbor(u) = " << ((this->adj[u].size() > 0) ? this->adj[u][0] : -1) << endl;return (this->adj[u].size() > 0) ? this->adj[u][0].v : -1;}int NextNeighbor(int u, int v) override {for(int i = 0; i < this->adj[u].size()-1 ;++i)if(this->adj[u][i].v == v) {// cout << "NextNeighbor(u, v) = " << this->adj[u][i+1] << endl;return this->adj[u][i+1].v;}return -1;}bool HasEdge(int u, int v) override {for(const ArcNode & i: adj[u])if(i.v == v)return true;return false;}int GetEdgeValue(int u, int v) override {for(const ArcNode & i: adj[u])if(i.v == v)return i.data;throw logic_error("u->v not exist");}vector<int> GetInDegree() override {vector<int> inDegree(vexNum);for(const vector<ArcNode> & vec: adj)for(const ArcNode & next: vec)inDegree[next.v]++;return inDegree;} };

總結

以上是生活随笔為你收集整理的DFS判断回路及回路个数的全部內容,希望文章能夠幫你解決所遇到的問題。

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