poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)
/**
problem: http://poj.org/problem?id=3177
tarjan blog: https://blog.csdn.net/reverie_mjp/article/details/51704523 v 为下一结点, u为当前结点
如果low[v] > dfn[u] 则 边(u,v)为桥
缩点后剩下的所有边都为桥(缩点后即为树结构)
将叶子结点相连使其成为双联通分量为最优解
所以:
添加(leaf + 1) / 2 条边即可使图成为双联通图
**/
#include<stdio.h>
#include<stack>
#include<algorithm>
using namespace std; class Graphics{
const static int MAXN = ;
const static int MAXM = * ;
private:
struct Edge{
int to, next;
bool bridge;
}edge[MAXM];
struct Point{
int dfn, low, color;
}point[MAXN];
int first[MAXN], sign, sumOfPoint, dfnNum, colorNum;
bool vis[MAXN];
stack<int> stk;
void tarjan(int u, int preEdge = -){
point[u].low = dfnNum;
point[u].dfn = dfnNum ++;
vis[u] = true;
stk.push(u);
for(int i = first[u]; i != -; i = edge[i].next){
int to = edge[i].to;
if((i^) == preEdge) continue; /// 由于是双向边,防止由该边跑回原来的点
if(!point[to].dfn){
tarjan(to, i);
point[u].low = min(point[u].low, point[to].low);
if(point[to].low > point[u].dfn){
edge[i].bridge = true;
edge[i^].bridge = true;
}
}else if(vis[to]){
point[u].low = min(point[to].dfn, point[u].low);
}
}
if(point[u].dfn == point[u].low){
vis[u] = false;
point[u].color = ++ colorNum;
while(stk.top() != u){
point[stk.top()].color = colorNum;
vis[stk.top()] = false;
stk.pop();
}
stk.pop();
}
}
public:
void init(int n){
sumOfPoint = n;
for(int i = ; i <= n; i ++){
first[i] = -;
vis[i] = ;
}
sign = colorNum = ;
dfnNum = ;
}
void addEdgeOneWay(int u, int v){
edge[sign].to = v;
edge[sign].next = first[u];
edge[sign].bridge = false;
first[u] = sign ++;
}
void addEdgeTwoWay(int u, int v){
addEdgeOneWay(u, v);
addEdgeOneWay(v, u);
}
void tarjanAllPoint(){
for(int i = ; i <= sumOfPoint; i ++){
if(!point[i].dfn)
tarjan(i);
}
}
int getAns(){
int *degree = new int[sumOfPoint+];
int ans = ;
for(int i = ; i <= sumOfPoint; i ++){
degree[i] = ;
}
tarjanAllPoint();
for(int i = ; i <= sumOfPoint; i ++){
for(int j = first[i]; j != -; j = edge[j].next){
int to = edge[j].to;
if(edge[j].bridge){
degree[point[to].color] ++;
}
}
}
for(int i = ; i <= sumOfPoint; i ++){
if(degree[i] == ){
ans ++;
}
}
delete []degree; return (ans + ) / ;
}
}graph; int main(){
int f, r;
scanf("%d%d", &f, &r);
graph.init(f);
while(r --){
int a, b;
scanf("%d%d", &a, &b);
graph.addEdgeTwoWay(a, b);
}
printf("%d\n", graph.getAns());
return ;
}
ps:
防止由该边跑回原来的点不能判断(点)而要判断(边)即
这么写是有bug的
例如:重边
poj 3177 Redundant Paths 求最少添加几条边成为双联通图: tarjan O(E)的更多相关文章
- tarjan算法求桥双连通分量 POJ 3177 Redundant Paths
POJ 3177 Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 12598 Accept ...
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...
- poj 3177 Redundant Paths(tarjan边双连通)
题目链接:http://poj.org/problem?id=3177 题意:求最少加几条边使得没对点都有至少两条路互通. 题解:边双连通顾名思义,可以先求一下连通块显然连通块里的点都是双连通的,然后 ...
- poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11047 Accepted: 4725 ...
- POJ 3177 Redundant Paths(边双连通的构造)
Redundant Paths Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13717 Accepted: 5824 ...
- POJ 3177——Redundant Paths——————【加边形成边双连通图】
Redundant Paths Time Limit:1000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
- POJ 3177 Redundant Paths (tarjan边双连通分量)
题目连接:http://poj.org/problem?id=3177 题目大意是给定一些牧场,牧场和牧场之间可能存在道路相连,要求从一个牧场到另一个牧场要有至少两条以上不同的路径,且路径的每条pat ...
- POJ 3177 Redundant Paths(Tarjan)
题目链接 题意 : 一个无向连通图,最少添加几条边使其成为一个边连通分量 . 思路 :先用Tarjan缩点,缩点之后的图一定是一棵树,边连通度为1.然后找到所有叶子节点,即度数为1的节点的个数leaf ...
- POJ - 3177 Redundant Paths (边双连通缩点)
题意:在一张图中最少可以添加几条边,使其中任意两点间都有两条不重复的路径(路径中任意一条边都不同). 分析:问题就是最少添加几条边,使其成为边双连通图.可以先将图中所有边双连通分量缩点,之后得到的就是 ...
随机推荐
- 基于forms组件和Ajax实现注册功能
一.基于forms组件的注册页面设计 1.运用forms组件的校验字段功能实现用户注册 views.py: (在钩子中代码解耦,将form放在cnblog/blog/Myforms.py中) f ...
- 2018.10.23NOIP模拟赛解题报告
心路历程 预计得分:\(100 + 50 + (10 \sim 50)\) 实际得分:\(100 + 10 + 50\) 这可能是我打的最懵逼的一场考试没有之一.. T1两个小时才做出来也是醉了. T ...
- 首页的css
html,body{ margin:; padding:; background-color: lavenderblush; } a{ color:darkgray; } li{ list-style ...
- Python爬虫《爬取get请求的页面数据》
一.urllib库 urllib是Python自带的一个用于爬虫的库,其主要作用就是可以通过代码模拟浏览器发送请求.其常被用到的子模块在Python3中的为urllib.request和urllib. ...
- CSS 兼容性支持
CSS 兼容性支持 在一个CSS属性还没有成为标准之前,各浏览器厂商已经做了这个属性的实现,可能各浏览器实现不尽相同,所以加入属性前缀区分. safari , chrome:-webkit- oper ...
- .Net中会存在内存泄漏吗
所谓内存泄露就是指一个不再被程序使用的对象或变量一直被占据在内存中..Net 中有垃圾回收机制,它可以保证一对象不再被引用的时候,即对象编程了孤儿的时候,对象将自动被垃圾回收器从内存中清除掉.虽然.N ...
- Azure镜像市场再下一城,中标软件入驻开启Azure国产操作系统时代
近日,中标软件成功入驻 Azure 镜像市场,提供中标麒麟 Linux 的产品镜像服务,这样一来,中标麒麟也成为国内唯一能够在 Azure 公有云上运行的国产操作系统产品. 作为国内操作系统的领头羊, ...
- sqlserver row_number函数的用法
ROW_NUMBER()函数将针对SELECT语句返回的每一行,从1开始编号,赋予其连续的编号 必须和over一起使用 select *,ROW_NUMBER() over(order by prod ...
- Android下最小化程序到后台代码
procedure TForm1.Button4Click(Sender: TObject); var Intent: JIntent; begin Intent := TJIntent. ...
- Android(java)学习笔记26:File类的使用
1. File类的使用 package cn.itcast_01; import java.io.File; /* * 我们要想实现IO的操作,就必须知道硬盘上文件的表现形式. * 而Java就提供 ...