1184 : 连通性二·边的双连通分量

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老师找到了小Hi和小Ho,希望他俩帮忙。

老师告诉小Hi和小Ho:根据现在网络的情况,我们要将服务器进行分组,对于同一个组的服务器,应当满足:当组内任意一个连接断开之后,不会影响组内服务器的连通性。在满足以上条件下,每个组内的服务器数量越多越好。

比如下面这个例子,一共有6个服务器和7条连接:

其中包含2个组,分别为{1,2,3},{4,5,6}。对{1,2,3}而言,当1-2断开后,仍然有1-3-2可以连接1和2;当2-3断开后,仍然有2-1-3可以连接2和3;当1-3断开后,仍然有1-2-3可以连接1和3。{4,5,6}这组也是一样。

老师把整个网络的情况告诉了小Hi和小Ho,小Hi和小Ho要计算出每一台服务器的分组信息。

输入

第1行:2个正整数,N,M。表示点的数量N,边的数量M。1≤N≤20,000, 1≤M≤100,000

第2..M+1行:2个正整数,u,v。表示存在一条边(u,v),连接了u,v两台服务器。1≤u<v≤N

保证输入所有点之间至少有一条连通路径。

输出

第1行:1个整数,表示该网络的服务器组数。

第2行:N个整数,第i个数表示第i个服务器所属组内,编号最小的服务器的编号。比如分为{1,2,3},{4,5,6},则输出{1,1,1,4,4,4};若分为{1,4,5},{2,3,6}则输出{1,2,2,1,1,2}

样例输入
6 7
1 2
1 3
2 3
3 4
4 5
4 6
5 6
样例输出
2
1 1 1 4 4 4

解释:

如果我们删除掉一条边之后图的连通性改变了的话,这样的边(桥)是不是一定不属于双连通子图。

对于一个无向图,当我们把图中所有的桥都去掉以后,剩下的每一个区域就是我们要求的边的双连通分量。

一:直观的做法自然先用上周的算法求出所有桥,去掉所有桥之后再做DFS求出每一个连通子图。

二:“抽象"的算法,通过Tarjan算法当中巧妙地用一个栈来统计出每一个组内的节点:

           因为low[u] == dfn[u],对(parent[u],u)来说有dfn[u] > dfn[ parent[u] ],因此low[u] > dfn[ parent[u]

           

           所以(parent[u],u)一定是一个桥,那么此时栈内在u之前入栈的点和u被该桥分割

       

           则u和之后入栈的节点属于同一个组

  
将从u到栈顶所有的元素标记为一个组,并弹出这些元素。


#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn=;
const int maxm=;
int low[maxn],dfn[maxn],times;
int Laxt[maxm],Next[maxm],To[maxm],cnt;
int scc_cnt,scc[maxn],Min[maxn];
vector<int>G[maxn];
int head,tail,q[maxm];
void add(int u,int v){
Next[++cnt]=Laxt[u];
Laxt[u]=cnt;
To[cnt]=v;
} void dfs(int u,int pre)
{
q[++head]=u;
dfn[u]=low[u]=++times;
for(int i=Laxt[u];i;i=Next[i]){
int v=To[i];
if(pre==v) continue;
if(!dfn[v]){
dfs(v,u);
low[u]=min(low[u],low[v]);
}
else low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]){
scc_cnt++;
while(true){
int v=q[head--];
G[scc_cnt].push_back(v);
scc[v]=scc_cnt;
if(v==u) break;
}
}
} int main()
{
int n,m,i,j,u,v;
scanf("%d%d",&n,&m);
for(i=;i<=m;i++){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs(,);
for(i=;i<=scc_cnt;i++){//找最小
int Minnum=G[i][];
for(j=;j<G[i].size();j++){
Minnum=min(Minnum,G[i][j]);
}
Min[i]=Minnum;
}
printf("%d\n",scc_cnt);
for(i=;i<=n;i++)
printf("%d ",Min[scc[i]]);
return ;
}

HohoCoder 1184 : 连通性二·边的双连通分量(+原理证明)的更多相关文章

  1. hihoCoder 1184 连通性二·边的双连通分量

    #1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老 ...

  2. hihoCoder #1184 : 连通性二·边的双连通分量(边的双连通分量模板)

    #1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老 ...

  3. [HIHO1184]连通性二·边的双连通分量(双连通分量)

    题目链接:http://hihocoder.com/problemset/problem/1184 题意裸,写个博客记下输出姿势. /* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mi ...

  4. 图连通性【tarjan点双连通分量、边双联通分量】【无向图】

    根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...

  5. 双连通分量(点-双连通分量&边-双连通分量)

    概念: 双连通分量有点双连通分量和边双连通分量两种.若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图. 一个无向图中的每一个极大点(边)双连 ...

  6. hihoCoder #1190 : 连通性·四(点的双连通分量模板)

    时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho从约翰家回到学校时,网络所的老师又找到了小Hi和小Ho. 老师告诉小Hi和小Ho:之前的分组出了点问题,当服 ...

  7. tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)

    基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...

  8. 连通分量模板:tarjan: 求割点 &amp;&amp; 桥 &amp;&amp; 缩点 &amp;&amp; 强连通分量 &amp;&amp; 双连通分量 &amp;&amp; LCA(近期公共祖先)

    PS:摘自一不知名的来自大神. 1.割点:若删掉某点后.原连通图分裂为多个子图.则称该点为割点. 2.割点集合:在一个无向连通图中,假设有一个顶点集合,删除这个顶点集合,以及这个集合中全部顶点相关联的 ...

  9. Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】

    一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...

随机推荐

  1. Qt性能问题

    使用Qt库开发通信上位机软件,如串口.CAN总线等,涉及到接收界面高速刷新,会使CPU消耗率过高(20%以上),可能还会卡顿. 具体原因不知道,突然想放弃Qt了 ps: 1.问题出在界面刷新,会占据C ...

  2. Spring boot + jdbc学习笔记

    pom.xml: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www. ...

  3. java基础(7)--方法

    方法 Math.sqrt() 取平方 Math.pow(2,3) 2的3次方 方法(Method),就是数学函数(Function). 业务方面: 是功能,是动作,一般采用动词命名. 数据层面:是利用 ...

  4. 使用Xcode IDE写node.js

    最近在玩node.js 但是发现很多IDE就是用不顺手 后来发现Xcode可以剖析java script 于是试着使用Xcode来当做node.js的编辑器 首先,在Mac上必须先安装node.js的 ...

  5. JQuery -- 介绍,选择器及其示例, 基本选择器,层次选择器,过滤选择器,表单选择器

    1. 什么是jQuery对象 jQuery 对象就是通过jQuery包装DOM对象后产生的对象. jQuery对象是jQuery独有的.如果一个对象是jQuery对象,那么它就可以使用jQuery里的 ...

  6. Pandas重建索引

    重新索引会更改DataFrame的行标签和列标签.重新索引意味着符合数据以匹配特定轴上的一组给定的标签. 可以通过索引来实现多个操作 - 重新排序现有数据以匹配一组新的标签. 在没有标签数据的标签位置 ...

  7. scala学习手记8 - 自适应的默认做法

    scala有一些默认做法,会让代码更简洁.更易读写,下面列出了这样几个特性: 1. 支持脚本.scala支持脚本,因此无须将所有的代码都放到类里.如果脚本可以满足需求,就将代码放到一个脚本里,无须再创 ...

  8. cmake的使用方法

    4. CMakeLists.txt剖析4.1 cmake_minimum_required命令 cmake_minimum_required (VERSION 2.6) 规定cmake程序的最低版本. ...

  9. 浅谈 django Models中的跨表

    跨表操作在数据库操作非常常用,虽然其会降低读取数据的性能,但是它能节约数据在硬盘中的占用,优化数据表的结构和各自之间的关系. 在sql中,一般跨表需要用到 join 关键字 select * from ...

  10. vmware配置网卡

    虚拟机网络配置 1. 启用VMWare虚拟网卡 如果没有查看到vmnet8这个网络连接,打开VMWare, 2. 设置虚拟机:选中安装好的虚拟机右键设置. 3. 设置虚拟机系统. 指令:vi /etc ...