poj 3177 Redundant Paths(边双连通分量+缩点)★
来源:互联网 发布:sql数据库实训总结 编辑:程序博客网 时间:2024/04/29 21:55
题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走。现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立的路。两条独立的路是指:没有公共边的路,但可以经过同一个中间顶点。
分析:在同一个边双连通分量中,任意两点都有至少两条独立路可达,所以同一个边双连通分量里的所有点可以看做同一个点。
缩点后,新图是一棵树,树的边就是原无向图的桥。
现在问题转化为:在树中至少添加多少条边能使图变为双连通图。
结论:添加边数=(树中度为1的节点数+1)/2
具体方法为,首先把两个最近公共祖先最远的两个叶节点之间连接一条边,这样可以把这两个点到祖先的路径上所有点收缩到一起,因为一个形成的环一定是双连通的。然后再找两个最近公共祖先最远的两个叶节点,这样一对一对找完,恰好是(leaf+1)/2次,把所有点收缩到了一起。
其实求边双连通分量和求强连通分量差不多,每次访问点的时候将其入栈,当low[u]==dfn[u]时就说明找到了一个连通的块,则栈内的所有点都属于同一个边双连通分量,因为无向图要见反向边,所以在求边双连通分量的时候,遇到反向边跳过就行了。
#include <set>#include <map>#include <stack>#include <queue>#include <deque>#include <cmath>#include <vector>#include <string>#include <cstdio>#include <cstdlib>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define L(i) i<<1#define R(i) i<<1|1#define INF 0x3f3f3f3f#define pi acos(-1.0)#define eps 1e-12#define maxn 300100#define MOD 1000000007const int N = 5000 + 5;const int M = 10000 + 5;struct EDGE{ int v,next;}edge[M*2];int head[N],low[N],dfn[N],belong[N],degree[N],sta[M],instack[M];int g,cnt,top,scc;int min(int a,int b){ return a < b ? a : b;}void AddEdge(int u,int v){ edge[g].v = v; edge[g].next = head[u]; head[u] = g++;}void Tarjan(int u,int fa){ low[u] = dfn[u] = ++cnt; sta[++top] = u; instack[u] = 1; for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].v; if(i == (fa^1)) continue; if(!dfn[v]) { Tarjan(v,i); low[u] = min(low[u],low[v]); } else if(instack[v]) low[u] = min(low[u],dfn[v]); } if(dfn[u] == low[u]) { scc++; while(1) { int v = sta[top--]; instack[v] = 0; belong[v] = scc; if(v == u) break; } }}int main(){ int n,m,u,v; scanf("%d%d",&n,&m); g = cnt = top = scc = 0; memset(head,-1,sizeof(head)); memset(low,0,sizeof(low)); memset(dfn,0,sizeof(dfn)); memset(instack,0,sizeof(instack)); memset(degree,0,sizeof(degree)); for(int i = 0; i < m; i++) { scanf("%d%d",&u,&v); AddEdge(u,v); AddEdge(v,u); } for(int i = 1; i <= n; i++) if(!dfn[i]) Tarjan(1,-1); for(int i = 1; i <= n; i++) { for(int j = head[i]; j != -1; j = edge[j].next) { v = edge[j].v; if(belong[i] != belong[v]) degree[belong[i]]++; } } int sum = 0; for(int i = 1; i <= n; i++) if(degree[i] == 1) sum++; int ans = (sum+1)/2; printf("%d\n",ans); return 0;}
0 0
- POJ 3177 Redundant Paths(边双连通分量+缩点)
- poj 3177 Redundant Paths 边双连通分量+缩点
- POJ 3177 Redundant Paths 边双连通分量+缩点
- POJ 3177 Redundant Paths(边双连通分量+缩点)
- POJ 3177 Redundant Paths(边双连通分量+缩点)
- POJ 3177 Redundant Paths(边双连通分量+缩点)
- poj 3177 Redundant Paths(边双连通分量+缩点)★
- POJ 3177 / POJ 3352 : Redundant Paths / Road Construction - 边双连通分量,缩点
- Poj 3352 Road Construction & Poj 3177 Redundant Paths(边双连通分量+缩点)
- poj 3177 Redundant Paths(双连通分量)
- poj3177 Redundant Paths(边双连通分量+缩点)
- 【POJ3177】Redundant Paths-边双连通分量+缩点
- POJ 3177 Redundant Paths 边的双连通分量
- [边双连通分量] poj 3177 Redundant Paths
- POJ 3177 Redundant Paths(边双连通分量,3级)
- POJ 3177 Redundant Paths / 边双连通分量
- poj 3177 Redundant Paths 边双连通分量
- POJ 3177 Redundant Paths(边双连通分量)
- 操作系统
- Hibernate与Mybatis的区别要点整理
- 【PHP】强大的filter_var
- bzoj 2120: 数颜色
- JavaScript做浏览器检测
- poj 3177 Redundant Paths(边双连通分量+缩点)★
- C语言小知识
- Spring依赖注入
- hiho 1015 KMP
- C++虚函数定义
- soapui 测试 rest webservice Post方式接口
- Cesium学习(1)--geoserver+cesium创建离线环境下的web三维球
- 安装和配置VNC服务器的法则
- 中国余数定理和POJ1006:Biorhythms