DFS判断回路及回路个数
生活随笔
收集整理的這篇文章主要介紹了
DFS判断回路及回路个数
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
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); // 將當前結(jié)點加入路徑// 遍歷u每一個鄰接點vfor(int v = G.FirstNeighbor(u); v >= 0 ;v = G.NextNeighbor(u, v)) { if(!visited[v])__topSort_DFS(G, v, visited, cycleNum, path);// 對于已訪問過的鄰接點,需要判斷其是否構(gòu)成回路(當然,path需要至少3個結(jié)點才能構(gòu)成回路)elseif(path.size() >= 3 ){// 如果邊u->v指向路徑上的一個結(jié)點(路徑上的結(jié)點都是已訪問結(jié)點),說明存在一條回路// path.size()-2的目的就是排除路徑中最近的兩個結(jié)點:結(jié)點u自身和結(jié)點u的前驅(qū)結(jié)點,因為這兩種情況不能形成回路for(int i = 0;i < path.size()-2;++i) {if(topSeq[i] == v)cycleNum++;}}}path.pop(); // 當遍歷一條路徑到盡頭時,便會隨著路徑進行回溯,于是將當前結(jié)點出棧以回溯 } // 使用DFS判斷回路 void topSort_DFS(Graph & G) {vector<int> visited(G.vexNum, false);stack<int> path; // 存放DFS每一次可能的路徑short cycleNum = 0; // 可記錄圖中存在的回路數(shù)量// 遍歷所有的連通分量for(int u = 0; u < G.vexNum ; ++u) {if(!visited[u]) {cycleNum = false; // 對于每一個連通分量都判斷回路__topSort_DFS(G, u, visited, cycleNum, path);}}cout << "回路個數(shù)為:" << 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;// 圖——抽象數(shù)據(jù)結(jié)構(gòu) struct Graph { public:static const int MAXVERTEX;static const int INF;int vexNum; // 頂點數(shù)int arcNum; // 邊數(shù)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)的權(quán)重virtual vector<int> GetInDegree() = 0; // 得到該圖的入度表}; const int Graph::INF = 0xffffff; const int Graph::MAXVERTEX = 100;// 圖——鄰接矩陣表示 struct GraphAM: public Graph {int edge[MAXVERTEX][MAXVERTEX]; // 存放邊權(quán)重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;} };總結(jié)
以上是生活随笔為你收集整理的DFS判断回路及回路个数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于topcoder的一些资料总结与实践
- 下一篇: 修复exe文件关联