关节点算法
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <vector> 5 6 using namespace std; 7 #define MAXN 1000 8 int low[MAXN],visit[MAXN]; // low[i] = min(visit[i],visist[j],low[w]); j 是 回路的父值,w是儿子值 9 int pointNum,edgeNum; 10 int count; // 统计遍历的顺序 11 12 int dfsArticul(vector<vector<int> > G,int v0) { // 最小的low[]值 13 int min = visit[v0] = ++count; 14 for (int i = 0;i < G[v0].size();i++) { 15 int w = G[v0][i]; 16 if (visit[w] == 0) { 17 low[w] = dfsArticul(G,w); 18 if (low[w] < min) min = low[w]; 19 if (low[w] >= visit[v0]) cout << v0 << endl; 20 } 21 else if (visit[w] < min) { 22 min = visit[w]; 23 } 24 } 25 return low[v0] = min; 26 } 27 28 void findArticul(vector <vector<int> > G) { 29 visit[0] = 1; 30 count = 1; 31 for (int i = 1;i < pointNum;i++) { 32 visit[i] = 0; 33 } 34 int p = G[0][0]; 35 dfsArticul(G,p); 36 if (count < pointNum) { // 父节点是否有两个子树 37 cout << p << endl; 38 for (int i = 1;i < G[0].size();i++) { 39 int w = G[0][i]; 40 if (visit[w] == 0) 41 dfsArticul(G,w); 42 } 43 } 44 } 45 46 int main () { 47 // freopen("1.in","r",stdin); 48 vector <vector<int> > G; // 邻接表 49 cin >> pointNum >> edgeNum; // 点的个数,边的个数 50 G.resize(pointNum + 1); 51 for (int i = 0;i < pointNum;i++) G[i].clear(); 52 for (int i = 0;i < edgeNum;i++) { 53 int x,y; 54 cin >> x >> y; // 边的起点,和终点 55 G[x].push_back(y); 56 G[y].push_back(x); 57 } 58 findArticul(G); 59 }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。