首页 > 代码库 > ZOJ 2588 Burning Bridges(无向图求割边)
ZOJ 2588 Burning Bridges(无向图求割边)
ZOJ 2588 Burning Bridges
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2588
题意:给定一个无向图连通图,(其中可能有重边),要求去掉一条边之后,使得整个图不再连通。输出这些符合条件的边的序号。
思路:这就是一个简单的无向图求割边,需要注意的是这个无向图有重边,重边一定不是割边。
代码:
/*========================================= 无向图求割点和桥 复杂度:O(E + V) 割点: 1:若k为深搜树的根Root,当且仅当k的儿子数(分支数)>=2时k为割点; 2:若k为搜索树的中间结点(即k既不为根也不为叶),那么k必然有father和son,若low[son]>= dfn[k],则k必然为割点。 割桥: 如果low[v] > dfn[u] 则(u,v)为割桥 (需要判断是否有重边,如果有重边一定不是割边) =========================================*/ /* ID: wuqi9395@126.com PROG: LANG: C++ */ #include<map> #include<set> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<string> #include<fstream> #include<cstring> #include<ctype.h> #include<iostream> #include<algorithm> using namespace std; #define INF (1<<30) #define PI acos(-1.0) #define mem(a, b) memset(a, b, sizeof(a)) #define rep(i, a, n) for (int i = a; i < n; i++) #define per(i, a, n) for (int i = n - 1; i >= a; i--) #define eps 1e-6 #define debug puts("===============") #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second #define SZ(x) ((int)(x).size()) #define POSIN(x,y) (0 <= (x) && (x) < n && 0 <= (y) && (y) < m) typedef long long ll; typedef unsigned long long ULL; const int maxn = 11000; const int maxm = 110000; int n, m; struct node { int v, id, tot; node(int _v, int _id, int _tot) { v = _v, id = _id, tot = _tot; } }; vector<node> g[maxn]; int dfn[maxn], low[maxn], vis[maxn], sub[maxn]; //sub记录每个割点分为多少块 bool cut[maxn]; int bridge[maxm], cnt; void dfs(int u, int f, int dep) { vis[u] = 1; dfn[u] = low[u] = dep; int child = 0; for (int i = 0; i < g[u].size(); i++) if (g[u][i].v != f) { int v = g[u][i].v; if (vis[v] == 1 && dfn[v] < low[u]) low[u] = dfn[v]; //回边更新low值 if (vis[v] == 0) { dfs(v, u, dep + 1); child++; if (low[v] < low[u]) low[u] = low[v]; //通过儿子回到祖先 if (low[v] > dfn[u] && g[u][i].tot == 1) bridge[cnt++] = g[u][i].id; } } vis[u] = 2; } void cut_bridge() { cnt = 0; memset(vis, 0, sizeof(int) * (n + 10)); dfs(1, -1, 0); //i为一个点 //如果多个连通块,需要对每一个连通块调用dfs } int main () { int T; scanf("%d", &T); while(T--) { scanf("%d%d", &n, &m); for (int i = 0; i <= n; i++) g[i].clear(); int u, v; for (int i = 1; i <= m; i++) { scanf("%d%d", &u, &v); bool flag = false; for (int j = 0; j < g[u].size(); j++) if (g[u][j].v == v) { g[u][j].tot++; flag = true; break; } if (flag) for (int j = 0; j < g[v].size(); j++) if (g[v][j].v == u) { g[v][j].tot++; break; } if (!flag) g[u].pb(node(v, i, 1)), g[v].pb(node(u, i, 1)); } cut_bridge(); sort(bridge, bridge + cnt); printf("%d\n", cnt); rep(i, 0, cnt) printf("%d%c", bridge[i], i == cnt - 1 ? '\n' : ' '); if (T > 0) puts(""); } return 0; }
ZOJ 2588 Burning Bridges(无向图求割边)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。