双连通分量 Road Construction POJ - 3352
@[双连通分量]
题意:
有一个 n 个点 m 条边的无向图,问至少添加几条边,能让该图任意缺少一条边后还能相互连通。
双连通分量定义:
在无向连通图中,如果删除该图的任何一个结点都不能改变该图的连通性,则该图为双连通的无向图。一个连通的无向图是双连通的,当且仅当它没有关节点(这里面节点可换成边:分点双连通分量 ,分边双连通分量)。
思路:
首先缩点成树;
与强连通分量缩点有所不同:记录父节点 ,不返回父节点 (意味着一条边只能从任意方向走一次) ;如果已经走过 ,直接可更新low值(目前理解:若这个点 B 已经走过,出栈后还能再次通过 A 访问到,说明从 B 也能访问到 A ,所以不需要是否在栈中的判断,在强连通分量中,因为是单向,所以只能从 A -> B ,需要是否在栈中的判断)。
试了一下加上栈的判断也对:因为访问B的时候直接就通过B 把 A 访问了,不会等到 A 去访问 B 。
缩点成树之后:
统计有 ans 个双连通分量只有一条边且只与一个双连通分量相连,(ans+1)/2 就是至少要加的边数
撸代码
#include<stdio.h>
#include<string.h>
#include<stack>
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 1010
struct node
{
int to,nex;
} edge[N*2];
int cost[N],dfn[N],low[N],belong[N],head[N];
bool instack[N];
int in[N];
int cnt,cir,index;
stack<int>s;
vector<int>point[N];
void init()
{
cnt=0;
cir=0;
index=0;
while(!s.empty())
s.pop();
for(int i=0; i<N; i++)
{
point[i].clear();
head[i]=-1;
in[i]=0;
instack[i]=false;
dfn[i]=0;
low[i]=0;
belong[i]=0;
}
}
void addEdge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].nex=head[u];
head[u]=cnt++;
}
/*求双连通分量*/
void Tarjan(int u,int fa)
{
dfn[u]=low[u]=++index;
instack[u]=true;
s.push(u);
for(int i=head[u]; i!=-1; i=edge[i].nex)
{
int v=edge[i].to;
if(v==fa)
continue;
if(!dfn[v])
{
Tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else //if(instack[v])
{/*走过且不在栈中*/
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
int node;
++cir;
do
{
node=s.top();
s.pop();
belong[node]=cir;
point[cir].push_back(node);
instack[node]=false;
}
while(node!=u);
}
return ;
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
init();
int a,b;
for(int i=0; i<m; i++)
{
scanf("%d%d",&a,&b);
addEdge(a,b);
addEdge(b,a);
}
for(int i=1; i<=n; i++)
if(!dfn[i])
Tarjan(i,i);
/*直到每个点所属的强连通分量*/
// printf("cir = %d\n",cir);
// for(int i=1;i<=cir;i++)
// {
// printf("cnt [%d]:",i);
// for(int j=0;j<point[i].size();j++)
// printf("%d ",point[i][j]);
// printf("\n");
// }
for(int i=1; i<=n; i++)
{
for(int j=head[i]; j!=-1; j=edge[j].nex)
{
/*!根据统计边 统计连通分量之间的度*/
a=belong[i];
b=belong[edge[j].to];
if(a!=b)
{
in[a]++;
in[b]++;
}
}
}
int ans=0;
for(int i=1; i<=cir; i++)
{
if(in[i]==2)
ans++;
}
printf("%d\n",(ans+1)/2);
}
return 0;
}
双连通分量 Road Construction POJ - 3352的更多相关文章
- Tarjan算法求解桥和边双连通分量(附POJ 3352 Road Construction解题报告)
http://blog.csdn.net/geniusluzh/article/details/6619575 在说Tarjan算法解决桥和边双连通分量问题之前我们先来回顾一下Tarjan算法是如何 ...
- POJ 3177 Redundant Paths & POJ 3352 Road Construction(双连通分量)
Description In order to get from one of the F (1 <= F <= 5,000) grazing fields (which are numb ...
- POJ 3352 Road Construction(边—双连通分量)
http://poj.org/problem?id=3352 题意: 给出一个图,求最少要加多少条边,能把该图变成边—双连通. 思路:双连通分量是没有桥的,dfs一遍,计算出每个结点的low值,如果相 ...
- POJ 3352 Road Construction(边双连通分量,桥,tarjan)
题解转自http://blog.csdn.net/lyy289065406/article/details/6762370 文中部分思路或定义模糊,重写的红色部分为修改过的. 大致题意: 某个企业 ...
- POJ 3352 Road Construction (边双连通分量)
题目链接 题意 :有一个景点要修路,但是有些景点只有一条路可达,若是修路的话则有些景点就到不了,所以要临时搭一些路,以保证无论哪条路在修都能让游客到达任何一个景点 思路 :把景点看成点,路看成边,看要 ...
- POJ 3177 Redundant Paths POJ 3352 Road Construction(双连接)
POJ 3177 Redundant Paths POJ 3352 Road Construction 题目链接 题意:两题一样的.一份代码能交.给定一个连通无向图,问加几条边能使得图变成一个双连通图 ...
- POJ 3352 Road Construction 双联通分量 难度:1
http://poj.org/problem?id=3352 有重边的话重边就不被包含在双连通里了 割点不一定连着割边,因为这个图不一定是点连通,所以可能出现反而多增加了双连通分量数的可能 必须要用割 ...
- poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】
Road Construction Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 10141 Accepted: 503 ...
- POJ3352 Road Construction (双连通分量)
Road Construction Time Limit:2000MS Memory Limit:65536KB 64bit IO Format:%I64d & %I64u Sub ...
随机推荐
- 通过nodejs实现文件的上传
通过nodejs实现文件的上传 主要内容 本文将用来讲述如何通过nodejs进行文件上传,将会涉及到以下知识点: 通过express模块进行服务器的搭建 通过multer模块将上传的文件保存到指定目录 ...
- Falsk 路由简析
添加路由 我们熟知添加路由的方式是装饰器: @app.route('/') def hello_world(): return 'Hello World!' #访问web得到 'Hello World ...
- 网络工程师和Linux运维工程师有什么区别?学哪个比较好?
网络工程师和Linux运维工程师有什么区别?学哪个比较好? 机缘巧合下,我进入了一家从事vpn与系统集成的公司,很感谢公司能留下我这个非网络工程专业的毕业生,从对网络一窍不通,慢慢可以自己独立完成工作 ...
- Simulink仿真入门到精通(十七) Simulink代码生成技术详解
17.1 基于模型的设计 基于模型设计是一种流程,较之传统软件开发流程而言,使开发者能够更快捷.更高效地进行开发.适用范围包括汽车电子信号处理.控制系统.通信行业和半导体行业. V字模型开发流程整体描 ...
- [译]ABP框架v2.3.0已经发布!
在新冠病毒的日子里,我们发布了ABP框架v2.3, 这篇文章将说明本次发布新增内容和过去的两周我们做了什么. 关于新冠病毒和我们的团队 关于冠状病毒的状况我们很难过.在Volosoft的团队,我们有不 ...
- 会话存储sessionStorage
会话存储的工作方式和本地存储的工作方式很接近,不同之处在于数据是各个浏览器上下文私有的,会在文档被关闭时移除(注意是被关闭时才移除,刷新是不会移除的).我们通过全局sessionStorage访问会话 ...
- 使用Netty如何解决拆包粘包的问题
首先,我们通过一个DEMO来模拟TCP的拆包粘包的情况:客户端连续向服务端发送100个相同消息.服务端的代码如下: AtomicLong count = new AtomicLong(0); NioE ...
- python turtle笔记
Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x.纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令的控制,在这个平面坐标系中移动,从而在它 ...
- vue使用lodop打印控件实现浏览器兼容打印
前言 此控件直接进行打印底部会有水印,通过官网购买可以解决: 如不想购买,可先执行预览,弹出预览框进行打印: 需要用到的js文件和api文档附后,请注意查看. 首先需要在局部或全局引入LodopFun ...
- 【开源】使用Angular9和TypeScript开发RPG游戏
RPG系统构造 通过对于斗罗大陆小说的游戏化过程,熟悉Angular的结构以及使用TypeScript的面向对象开发方法. 项目地址 人物 和其他RPG游戏类似,游戏里面的人物角色大致有这样的一些属性 ...