图论分支-Tarjan初步-点双连通分量
上一次我们讲到了边双,这次我们来看点双。
说实话来说,点双比边双稍微复杂一些;
学完边双,我们先看一道题


第一问都不用说了吧,多余的道路,明显的割边。
是不是首先想到用边双,但是我们来看一个图:

有点丑,但是凑活看吧。
它是一个边双,但是!!!!它竟然没有冲突的边!!!
此时我们就要用点双了(是不是想打死我,竟然没讲,先坑人)
先看概念

都说概念是非常重要的,但是概念似乎有点笼统,可以附图解说

点双的一大特点是它可以重复用点,而那个点就是割点,而我们的缩点操作也是用割点连接各个点双的。
那么我们来看算法,我们在Tarjan时,用栈去维护点双,之后用vector去储存。
我们直接来看上面的题,就会明白这不是点双吗?
然后寻找规律,我们会发现,每一个点双中,只要边个数大于点个数,那么这里的边都是冲突的,那么我们的Code就跃然纸上了
#include<bits/stdc++.h>
#define maxn 10007
#define M 100007
using namespace std;
int n,m,cent=,t,head[maxn],low[maxn],dfn[maxn],ans1,ans2;
int stackk[maxn],cnt,top,root,cut[maxn],col[maxn],vis[maxn];
int ol;
vector<int >dcc[maxn];
struct node{
int next,to;
}edge[M*]; inline void add(int u,int v){
edge[++cent]=(node){head[u],v};head[u]=cent;
} void Tarjan(int x,int fa){
dfn[x]=low[x]=++t;
stackk[++top]=x;//入栈
if(x==root&&head[x]==){//不联通时的孤立点
dcc[++cnt].push_back(x);
return ;
}
for(int i=head[x];i;i=edge[i].next){
int y=edge[i].to;
if(!dfn[y]){
Tarjan(y,i);
low[x]=min(low[x],low[y]);//与其他的一样
if(low[y]>=dfn[x]){
if(low[y]>dfn[x]) ans1++;//记录割边个数
int z;cnt++;
do{
z=stackk[top--];//从栈中取出
dcc[cnt].push_back(z);//存入
}while(z!=y);//停止条件,这个可以想一想为什么
dcc[cnt].push_back(x);//把割点也存进去
}
}else if((i^)!=fa) low[x]=min(low[x],dfn[y]);
}
} void clear(){
ans1=ans2=top=cnt=t=ol=;cent=;
memset(head,,sizeof head);
memset(low,,sizeof low);
memset(dfn,,sizeof dfn);
memset(stackk,,sizeof stackk);
memset(dcc,,sizeof dcc);
memset(col,,sizeof col);
memset(edge,,sizeof edge);
} int main(){
// freopen("way.in","r",stdin);
// freopen("way.out","w",stdout);
while(scanf("%d%d",&n,&m)){
if(n==&&m==)break;
clear();
int a,b;
for(int i=;i<=m;i++){
scanf("%d%d",&a,&b);
add(a+,b+),add(b+,a+);//由于点从零开始,那么我们+1即可
}
for(int i=;i<=n;i++){
if(!dfn[i]) root=i,Tarjan(i,-);
}
for(int i=;i<=cnt;i++,ol=){
for(int j=;j<dcc[i].size();j++){
vis[dcc[i][j]]=;//记录点双上的点
}
for(int k=;k<dcc[i].size();k++){
for(int j=head[dcc[i][k]];j;j=edge[j].next){
if(vis[edge[j].to]) ol++;//ol统计边数
}
}
if(ol/>dcc[i].size()) ans2+=ol/;//由于是双向边,ol会统计量词
memset(vis,,sizeof(vis));
}
printf("%d %d\n",ans1,ans2);
}
}
那么我们就应该懂了一些基本的概念,和简单的操作,那么,留一个彩蛋,我们该如何去缩点连接呢?
图论分支-Tarjan初步-点双连通分量的更多相关文章
- 图论分支-Tarjan初步-边双联通分量
本来应该先说强连通分量,但是有一定的分配,所以这个在下一篇博客将会见到. 这个本想连点连通分量一起讲,但是量有点大,所以我就分两步讲. 我们先看定义 再来看看图解 很容易就能发现,只要将割边断掉,然后 ...
- 图论分支-Tarjan初步-割点和割边
所谓割点(顶)割边,我们引进一个概念 割点:删掉它之后(删掉所有跟它相连的边),图必然会分裂成两个或两个以上的子图. 割边(桥):删掉一条边后,图必然会分裂成两个或两个以上的子图,又称桥. 这样大家就 ...
- hdu 2460(tarjan求边双连通分量+LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2460 思路:题目的意思是要求在原图中加边后桥的数量,首先我们可以通过Tarjan求边双连通分量,对于边 ...
- [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分)
[Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分) 题面 给出一个无向图,以及q条有向路径.问是否存在一种给边定向的方案,使得 ...
- C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建
最近在学图论相关的内容,阅读这篇博客的前提是你已经基本了解了Tarjan求点双. 由割点的定义(删去这个点就可使这个图不连通)我们可以知道,坍塌的挖煤点只有在割点上才会使这个图不连通,而除了割点的其他 ...
- Tarjan求点双连通分量
概述 在一个无向图中,若任意两点间至少存在两条“点不重复”的路径,则说这个图是点双连通的(简称双连通,biconnected) 在一个无向图中,点双连通的极大子图称为点双连通分量(简称双连通分量,Bi ...
- tarjan复习笔记 双连通分量,强连通分量
声明:图自行参考割点和桥QVQ 双连通分量 如果一个无向连通图\(G=(V,E)\)中不存在割点(相对于这个图),则称它为点双连通图 如果一个无向连通图\(G=(V,E)\)中不存在割边(相对于这个图 ...
- Codeforces Beta Round #89 (Div. 2) E. Bertown roads(Tarjan、边双连通分量)
题目链接:http://codeforces.com/problemset/problem/118/E 思路:首先要判断图是否是边双连通,这个Tarjan算法可以判断,若low[v] > dfn ...
- 6409. 【NOIP2019模拟11.06】困难的图论(Tarjan求点双)
题目描述 Description 给定由 n 个点 m 条边组成的无向连通图,保证没有重边和自环. 你需要找出所有边,满足这些边恰好存在于一个简单环中.一个环被称为简单环,当且仅当它包含的所有点都只在 ...
随机推荐
- gym-101350H
题意:给你一个字符串,判断是否为镜像串,镜像串的定义:是一个回文串且只能由对称的字母组成,比如W,M,这些,因为要镜像对称: 解题思路:首先判断一下这个字符串是不是全由对称字母组成,不是就不用继续了, ...
- mysql语句-DDL语句
SQL分类 1.DDL语句:数据定义语句,用来定义不同的数据段.数据库,表,列,索引等数据表对象,常用语句:create.drop.alter等. 2.DML语句:数据操作语句,用于添加.删除.更新和 ...
- qss 的使用
//设置样式表 QStringList qss; qss.append("QFrame{border:0px solid #00BB9E;}"); // qss.append(&q ...
- Codeforces518 D. Ilya and Escalator
传送门:>Here< 题意:有n个人排队做电梯,每个人必须等前面的人全部上了以后才能上.对于每秒钟,有p的概率选择上电梯,(1-p)的概率选择不上电梯.现在问t秒期望多少人上电梯 解题思路 ...
- Get Luffy Out * HDU - 1816(2 - sat 妈的 智障)
题意: 英语限制了我的行动力....就是两个钥匙不能同时用,两个锁至少开一个 建个图 二分就好了...emm....dfs 开头low 写成sccno 然后生活失去希望... #include & ...
- Gitbash如何支持交互式命令?如何让gitbash的命令不乱码?winpty是什么鬼?干嘛用的?
winpty 是一个 Windows 软件包,提供了类似 Unix pty-master 一样的接口,用于实现控制台程序之间的通讯.该软件包包括一个开发库 (libwinpty) 和一个用于 ygwi ...
- pip 安装第三方包提示Unknown or unsupported command 'install'
Unknown or unsupported command 'install' Unknown or unsupported command 'show' Unknown or unsupporte ...
- Palindrome Function HDU - 6156(数位dp)
要求m-n内在l-r进制下的是回文数的总个数. dp[进制][从第j为开始][目前到达第k位] = 总的方案数 dfs枚举目前的到达的位置,这个数开始的位置,进制,前导零,限制条件,然后枚举的时候如果 ...
- NOIp2018 复习笔记
其实也没什么用啦,只是来占个坑 OI知识 3367 [模板]并查集 就这么做啊 没什么其他的 就是可以做tarjan LCA和Kruskal的操作 //关键函数 int getfa(int t) { ...
- 【php】php分隔字符串为数组
工作中会经常分隔字符串为数组,我们可以用php内置函数str_split(),可是有时候字符串中包含中文,切割后会乱码,比如 print_r(str_split('dw氛围fesf',3)); 输出 ...