上一次我们讲到了边双,这次我们来看点双。

说实话来说,点双比边双稍微复杂一些;

学完边双,我们先看一道题

第一问都不用说了吧,多余的道路,明显的割边。

是不是首先想到用边双,但是我们来看一个图:

有点丑,但是凑活看吧。

它是一个边双,但是!!!!它竟然没有冲突的边!!!

此时我们就要用点双了(是不是想打死我,竟然没讲,先坑人)

先看概念

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

点双的一大特点是它可以重复用点,而那个点就是割点,而我们的缩点操作也是用割点连接各个点双的。

那么我们来看算法,我们在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初步-点双连通分量的更多相关文章

  1. 图论分支-Tarjan初步-边双联通分量

    本来应该先说强连通分量,但是有一定的分配,所以这个在下一篇博客将会见到. 这个本想连点连通分量一起讲,但是量有点大,所以我就分两步讲. 我们先看定义 再来看看图解 很容易就能发现,只要将割边断掉,然后 ...

  2. 图论分支-Tarjan初步-割点和割边

    所谓割点(顶)割边,我们引进一个概念 割点:删掉它之后(删掉所有跟它相连的边),图必然会分裂成两个或两个以上的子图. 割边(桥):删掉一条边后,图必然会分裂成两个或两个以上的子图,又称桥. 这样大家就 ...

  3. hdu 2460(tarjan求边双连通分量+LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2460 思路:题目的意思是要求在原图中加边后桥的数量,首先我们可以通过Tarjan求边双连通分量,对于边 ...

  4. [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分)

    [Codeforces 555E]Case of Computer Network(Tarjan求边-双连通分量+树上差分) 题面 给出一个无向图,以及q条有向路径.问是否存在一种给边定向的方案,使得 ...

  5. C++[Tarjan求点双连通分量,割点][HNOI2012]矿场搭建

    最近在学图论相关的内容,阅读这篇博客的前提是你已经基本了解了Tarjan求点双. 由割点的定义(删去这个点就可使这个图不连通)我们可以知道,坍塌的挖煤点只有在割点上才会使这个图不连通,而除了割点的其他 ...

  6. Tarjan求点双连通分量

    概述 在一个无向图中,若任意两点间至少存在两条“点不重复”的路径,则说这个图是点双连通的(简称双连通,biconnected) 在一个无向图中,点双连通的极大子图称为点双连通分量(简称双连通分量,Bi ...

  7. tarjan复习笔记 双连通分量,强连通分量

    声明:图自行参考割点和桥QVQ 双连通分量 如果一个无向连通图\(G=(V,E)\)中不存在割点(相对于这个图),则称它为点双连通图 如果一个无向连通图\(G=(V,E)\)中不存在割边(相对于这个图 ...

  8. Codeforces Beta Round #89 (Div. 2) E. Bertown roads(Tarjan、边双连通分量)

    题目链接:http://codeforces.com/problemset/problem/118/E 思路:首先要判断图是否是边双连通,这个Tarjan算法可以判断,若low[v] > dfn ...

  9. 6409. 【NOIP2019模拟11.06】困难的图论(Tarjan求点双)

    题目描述 Description 给定由 n 个点 m 条边组成的无向连通图,保证没有重边和自环. 你需要找出所有边,满足这些边恰好存在于一个简单环中.一个环被称为简单环,当且仅当它包含的所有点都只在 ...

随机推荐

  1. gym-101350H

    题意:给你一个字符串,判断是否为镜像串,镜像串的定义:是一个回文串且只能由对称的字母组成,比如W,M,这些,因为要镜像对称: 解题思路:首先判断一下这个字符串是不是全由对称字母组成,不是就不用继续了, ...

  2. mysql语句-DDL语句

    SQL分类 1.DDL语句:数据定义语句,用来定义不同的数据段.数据库,表,列,索引等数据表对象,常用语句:create.drop.alter等. 2.DML语句:数据操作语句,用于添加.删除.更新和 ...

  3. qss 的使用

    //设置样式表 QStringList qss; qss.append("QFrame{border:0px solid #00BB9E;}"); // qss.append(&q ...

  4. Codeforces518 D. Ilya and Escalator

    传送门:>Here< 题意:有n个人排队做电梯,每个人必须等前面的人全部上了以后才能上.对于每秒钟,有p的概率选择上电梯,(1-p)的概率选择不上电梯.现在问t秒期望多少人上电梯 解题思路 ...

  5. Get Luffy Out * HDU - 1816(2 - sat 妈的 智障)

    题意: 英语限制了我的行动力....就是两个钥匙不能同时用,两个锁至少开一个 建个图 二分就好了...emm....dfs  开头low 写成sccno  然后生活失去希望... #include & ...

  6. Gitbash如何支持交互式命令?如何让gitbash的命令不乱码?winpty是什么鬼?干嘛用的?

    winpty 是一个 Windows 软件包,提供了类似 Unix pty-master 一样的接口,用于实现控制台程序之间的通讯.该软件包包括一个开发库 (libwinpty) 和一个用于 ygwi ...

  7. pip 安装第三方包提示Unknown or unsupported command 'install'

    Unknown or unsupported command 'install' Unknown or unsupported command 'show' Unknown or unsupporte ...

  8. Palindrome Function HDU - 6156(数位dp)

    要求m-n内在l-r进制下的是回文数的总个数. dp[进制][从第j为开始][目前到达第k位] = 总的方案数 dfs枚举目前的到达的位置,这个数开始的位置,进制,前导零,限制条件,然后枚举的时候如果 ...

  9. NOIp2018 复习笔记

    其实也没什么用啦,只是来占个坑 OI知识 3367 [模板]并查集 就这么做啊 没什么其他的 就是可以做tarjan LCA和Kruskal的操作 //关键函数 int getfa(int t) { ...

  10. 【php】php分隔字符串为数组

    工作中会经常分隔字符串为数组,我们可以用php内置函数str_split(),可是有时候字符串中包含中文,切割后会乱码,比如 print_r(str_split('dw氛围fesf',3)); 输出 ...