HohoCoder 1184 : 连通性二·边的双连通分量(+原理证明)
1184 : 连通性二·边的双连通分量
描述
在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老师找到了小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 : 连通性二·边的双连通分量(+原理证明)的更多相关文章
- hihoCoder 1184 连通性二·边的双连通分量
#1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老 ...
- hihoCoder #1184 : 连通性二·边的双连通分量(边的双连通分量模板)
#1184 : 连通性二·边的双连通分量 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在基本的网络搭建完成后,学校为了方便管理还需要对所有的服务器进行编组,网络所的老 ...
- [HIHO1184]连通性二·边的双连通分量(双连通分量)
题目链接:http://hihocoder.com/problemset/problem/1184 题意裸,写个博客记下输出姿势. /* ━━━━━┒ギリギリ♂ eye! ┓┏┓┏┓┃キリキリ♂ mi ...
- 图连通性【tarjan点双连通分量、边双联通分量】【无向图】
根据 李煜东大牛:图连通性若干拓展问题探讨 ppt学习. 有割点不一定有割边,有割边不一定有割点. 理解low[u]的定义很重要. 1.无向图求割点.点双联通分量: 如果对一条边(x,y),如果low ...
- 双连通分量(点-双连通分量&边-双连通分量)
概念: 双连通分量有点双连通分量和边双连通分量两种.若一个无向图中的去掉任意一个节点(一条边)都不会改变此图的连通性,即不存在割点(桥),则称作点(边)双连通图. 一个无向图中的每一个极大点(边)双连 ...
- hihoCoder #1190 : 连通性·四(点的双连通分量模板)
时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho从约翰家回到学校时,网络所的老师又找到了小Hi和小Ho. 老师告诉小Hi和小Ho:之前的分组出了点问题,当服 ...
- tarjan算法与无向图的连通性(割点,桥,双连通分量,缩点)
基本概念 给定无向连通图G = (V, E)割点:对于x∈V,从图中删去节点x以及所有与x关联的边之后,G分裂为两个或两个以上不相连的子图,则称x为割点割边(桥)若对于e∈E,从图中删去边e之后,G分 ...
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(近期公共祖先)
PS:摘自一不知名的来自大神. 1.割点:若删掉某点后.原连通图分裂为多个子图.则称该点为割点. 2.割点集合:在一个无向连通图中,假设有一个顶点集合,删除这个顶点集合,以及这个集合中全部顶点相关联的 ...
- Tarjan应用:求割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)【转】【修改】
一.基本概念: 1.割点:若删掉某点后,原连通图分裂为多个子图,则称该点为割点. 2.割点集合:在一个无向连通图中,如果有一个顶点集合,删除这个顶点集合,以及这个集合中所有顶点相关联的边以后,原图变成 ...
随机推荐
- 跟着实例学习ZooKeeper的用法: 分布式锁
锁 分布式的锁全局同步, 这意味着任何一个时间点不会有两个客户端都拥有相同的锁. 可重入锁Shared Reentrant Lock 首先我们先看一个全局可重入的锁. Shared意味着锁是全局可见的 ...
- Java并发之Semaphore的使用
Java并发之Semaphore的使用 一.简介 今天突然发现,看着自己喜欢的球队发挥如此的棒,然后写着博客,这种感觉很爽.现在是半场时间,就趁着这个时间的空隙,说说Java并发包中另外一个重量级的类 ...
- flex NaN
如果该值为NaN(非数字),则返回true:否则返回false.public function isNaN(num:Number):Boolean 举例:NaN值不是int或uint数据类型的成员.f ...
- C# Json格式
using LitJson; //自定义Json类 JsonDataResult jsondata = new JsonDataResult() { Success = false }; HttpCo ...
- JavaScript消息机制入门篇
JavaScript这个语言本身就是建立在一种消息机制上的,所以它很容易处理异步回调和各种事件.这个概念与普通的编程语言基础是不同的,所以让很多刚接触JavaScript的人摸不着头脑.JavaScr ...
- Spring AOP(1)
- C++中map的用法
map的特性是,所有元素都会根据元素的减值自动被排序.map的所有元素都是pair,同时拥有实值(value)和键值(key).pair的第一个元素会被视为键值,第二个元素会被视为实值.map不允许两 ...
- javascript页面打印
打印本身比较简单,但要考虑到具体的需求.比如 1. 多浏览器: if (isIE()) { //打印预览 WebBrowser1.execWB(7, 1); } else { window.print ...
- QTableWidget 列排序
connect(uirecord.tableWidget->horizontalHeader(),SIGNAL(sectionClicked(int)),this,SLOT(record_sor ...
- flume-ng源码阅读memory-channel(原创)
org.apache.flume.channel.MemoryChannel类是Flume-NG的memory-channel. private LinkedBlockingDeque<Even ...