poj 3177 Redundant Paths (双连通)
2015-08-07 09:57
453 查看
http://poj.org/problem?id=3177
One visualization of the paths is:
Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.
Check some of the routes:
1 – 2: 1 –> 2 and 1 –> 6 –> 5 –> 2
1 – 4: 1 –> 2 –> 3 –> 4 and 1 –> 6 –> 5 –> 4
3 – 7: 3 –> 4 –> 7 and 3 –> 2 –> 5 –> 7
Every pair of fields is, in fact, connected by two routes.
看ζёСяêτ
- 小優YoU 的解析很明白的哦,讲述的太明白了
少在缩点树上增加多少条树边,使得这棵树变为一个双连通图”。
首先知道一条等式:
若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么
至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2
/article/1968984.html
One visualization of the paths is:
1 2 3 +---+---+ | | | | 6 +---+---+ 4 / 5 / / 7 +
Building new paths from 1 to 6 and from 4 to 7 satisfies the conditions.
1 2 3 +---+---+ : | | : | | 6 +---+---+ 4 / 5 : / : / : 7 + - - - -
Check some of the routes:
1 – 2: 1 –> 2 and 1 –> 6 –> 5 –> 2
1 – 4: 1 –> 2 –> 3 –> 4 and 1 –> 6 –> 5 –> 4
3 – 7: 3 –> 4 –> 7 and 3 –> 2 –> 5 –> 7
Every pair of fields is, in fact, connected by two routes.
看ζёСяêτ
- 小優YoU 的解析很明白的哦,讲述的太明白了
少在缩点树上增加多少条树边,使得这棵树变为一个双连通图”。
首先知道一条等式:
若要使得任意一棵树,在增加若干条边后,变成一个双连通图,那么
至少增加的边数 =( 这棵树总度数为1的结点数 + 1 )/ 2
/article/1968984.html
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <cstdlib> #include <limits> #include <queue> #include <stack> #include <vector> #include <map> using namespace std; #define N 5005 #define INF 0xfffffff #define PI acos (-1.0) #define EPS 1e-8 vector <vector <int> > G; int n, m, Time, ans, cnt, top; int low , dfn , ft , f , eg , Stack ; void Init (); void tarjan (int u, int fa); void solve (); int main () { while (~scanf ("%d%d", &n, &m)) { int a, b; Init (); while (m--) { scanf ("%d%d", &a, &b); G[a].push_back (b); G[b].push_back (a); } solve (); } return 0; } void Init () { G.clear (); G.resize (n+1); memset (low, 0, sizeof (low)); memset (dfn, 0, sizeof (dfn)); memset (Stack, 0, sizeof (Stack)); memset (f, 0, sizeof (f)); memset (ft, 0, sizeof (ft)); Time = top = ans = cnt = 0; } void tarjan (int u, int fa) { low[u] = dfn[u] = ++Time; Stack[top++] = u; f[u] = fa; int len = G[u].size (), v, k = 0; for (int i=0; i<len; i++) { v = G[u][i]; if (v == fa && !k)//如果有重边的话,第一条边可以不用走 { k++; continue; } if (!dfn[v]) { tarjan (v, u); low[u] = min (low[u], low[v]); } else low[u] = min (low[u], dfn[v]); } if (low[u] == dfn[u]) { do { v = Stack[--top]; ft[v] = cnt; }while (u != v); cnt++; } } void solve () { int deg = {0}; for (int i=1; i<=n; i++) if (!low[i]) tarjan (i, i); for (int i=1; i<=n; i++) { int v = f[i]; if (ft[i] != ft[v]) deg[ft[i]]++, deg[ft[v]]++;//计算叶子节点的度 } for (int i=0; i<cnt; i++) if (deg[i] == 1) ans++;//度为1 printf ("%d\n", (ans+1)/2); }
相关文章推荐
- Android studio用WiFi连接adb
- System V IPC vs POSIX IPC
- 最佳路由选择的原则与步骤————管理距离和度量值
- UVA 11020 Efficient Solutions+multiset的应用
- RegionServer功能职责
- sesearch
- oracle基本操作
- mysql忘记root密码的解决方法
- MySql更新优化策略
- 南邮 OJ 1912 E.V.O.L
- css 曲线阴影
- Triangle
- 动态规划 uva 1025
- Eclipse安装Freemarker Editor插件
- Java中的值传递和引用传递
- toad for oracle中文显示乱码
- toad for oracle中文显示乱码
- Centos7.1.1503中文编码下,tomcat service命令不支持UTF-8
- (C/C++学习笔记)Copy构造函数应用场景
- ionic 项目中创建侧边栏的具体流程分4步简单学会