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 }
复制代码

 



如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。
posted @   YHXo  阅读(20)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
点击右上角即可分享
微信分享提示