tarjan求割边割点模板
求割点:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 10; 4 int n, m, t, idx; 5 int tot, head[N], to[N << 1], nxt[N << 1]; 6 int dfn[N], low[N], st[N], top, deg[N];//deg[i] i属于点双的数量 7 vector<int> a[N]; 8 void add(int x, int y) { 9 nxt[++ tot] = head[x]; head[x] = tot; to[tot] = y; 10 } 11 void dfs(int u, int fa) { 12 dfn[u] = low[u] = ++ t; 13 st[++ top] = u; 14 for (int i = head[u]; i; i = nxt[i]) { 15 int v = to[i]; 16 if (v == fa) continue;//保证一直向下搜,不用打栈标记 17 if (!dfn[v]) { 18 dfs(v, u); 19 low[u] = min(low[u], low[v]); 20 if (low[v] >= dfn[u]) { 21 idx ++; 22 a[idx].push_back(u); 23 deg[u] ++; 24 int vv; 25 do { 26 vv = st[top --]; 27 a[idx].push_back(vv); 28 deg[vv] ++; 29 } while (vv != v); 30 } 31 } 32 else low[u] = min(low[u], dfn[v]); 33 } 34 } 35 int main() { 36 cin >> n >> m; 37 while (m --) { 38 int x, y; 39 cin >> x >> y; 40 add(x, y), add(y, x);//双向连边 41 } 42 for (int i = 1; i <= n; i ++) 43 if(!dfn[i]) dfs(i, 0), top = 0;//每次清空栈 44 int ans = 0; 45 for (int i = 1; i <= n; i ++) { 46 if (deg[i] > 1) ans ++; 47 } 48 printf("%d\n", ans); 49 for (int i = 1; i <= n; i ++) { 50 if (deg[i] > 1) printf("%d ", i); 51 } 52 /*for (int i = 1; i <= idx; i ++) { 53 printf("%d:", i); 54 for (int j = 0; j < a[i].size(); j ++) 55 printf("%d ", a[i][j]); 56 printf("\n"); 57 }*/ //输出每个点双中的点 58 return 0; 59 }
求割边:
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N = 1e5 + 10; 4 int tot, head[N], to[N << 1], nxt[N << 1]; 5 int dfn[N], low[N]; 6 int n, m, t, anscnt; 7 struct node { 8 int u, v; 9 }edge[N]; 10 bool cmp(node a, node b) { 11 if (a.u != b.u) return a.u < b.u; 12 else return a.v < b.v; 13 } 14 void add(int x, int y) { 15 nxt[++ tot] = head[x]; head[x] = tot; to[tot] = y; 16 } 17 void dfs(int u, int fa) { 18 dfn[u] = low[u] = ++ t; 19 for (int i = head[u]; i; i = nxt[i]) { 20 int v = to[i]; 21 if (v == fa) continue; 22 if (!dfn[v]) { 23 dfs(v, u); 24 low[u] = min(low[u], low[v]); 25 if (low[v] > dfn[u]) {//找到割边 26 anscnt ++; 27 edge[anscnt].u = min(u, v); 28 edge[anscnt].v = max(u, v); 29 } 30 } 31 else low[u] = min(low[u], dfn[v]); 32 } 33 } 34 int main() { 35 cin >> n >> m; 36 while (m --) { 37 int x, y; cin >> x >> y; 38 add(x, y), add(y, x); 39 } 40 for (int i = 1; i <= n; i ++) 41 if (!dfn[i]) dfs(i, 0); 42 sort(edge + 1, edge + anscnt + 1, cmp); 43 for (int i = 1; i <= anscnt; i ++) 44 printf("%d %d\n", edge[i].u, edge[i].v); 45 return 0; 46 }
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析