关节点算法

 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 << 0 << 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 }

 

转载于:https://www.cnblogs.com/xiaoshanshan/p/4199590.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值