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

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

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

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

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

有点丑,但是凑活看吧。

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

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

先看概念

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

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

那么我们来看算法,我们在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. Servlet篇 之 web服务器

    创建web项目,在web项目中创建html页面,然后把项目部署到web服务器里面,启动服务器之后,可以使用浏览器通过URL地址的方式,访问到web项目中的html页面了 Web服务器: 常用tomca ...

  2. Android与H5交互 原理与对比

    原文:  https://www.jianshu.com/p/345f4d8a5cfa 1.Android调用JS的方法有2种: (1)通过WebView的loadUrl() // 调用js中的函数: ...

  3. GitHub大佬:供计算机学习鉴黄功能的图片数据库

    ps:学无止境 想要构建一套鉴黄系统,必须有大量的真实图片供计算机进行学习,以便于区分开正常图片和黄色图片. 近期有位加拿大程序员在Github上传了图片列表,里面包含了大量图片地址可以供计算机进行学 ...

  4. pip 解决下载包速度慢的问题

    对于Python开发用户来讲,PIP安装软件包是家常便饭.但国外的源下载速度实在太慢,浪费时间.而且经常出现下载后安装出错问题.所以把PIP安装源替换成国内镜像,可以大幅提升下载速度,还可以提高安装成 ...

  5. P1216 数字三角形

    题目描述 观察下面的数字金字塔. 写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大.每一步可以走到左下方的点也可以到达右下方的点. 7 3 8 8 1 0 2 7 4 4 4 5 ...

  6. 前端 -- HTML内容

    HTML介绍 Wed服务本质 import socket sk = socket.socket() sk.bind(("127.0.0.1", 8080)) sk.listen(5 ...

  7. FastDFS安装与使用

    1. FastDFS介绍 FastDFS是一个开源的轻量级分布式文件系统,由跟踪服务器(tracker server).存储服务器(storage server)和客户端(client)三个部分组成, ...

  8. ubuntu 16.04 主题美化及终端美化

    如果你使用的是图形界面,你会发现ubuntu默认的界面真是丑的一批,所以简单美化一下: 1.安装unity-tweak-tool: sudo apt-get install unity-tweak-t ...

  9. session的基本原理及安全性

    1.session原理 提到session,大家肯定会联想到登录,登录成功后记录登录状态,同时标记当前登录用户是谁.功能大体上就是这个样子,但是今天要讲的不是功能,而是实现.通过探讨session的实 ...

  10. Codeforces Round #489 (Div. 2) E. Nastya and King-Shamans(线段树)

    题意 给出一个长度为 \(n\) 的序列 \(\{a_i\}\) , 现在会进行 \(m\) 次操作 , 每次操作会修改某个 \(a_i\) 的值 , 在每次操作完后你需要判断是否存在一个位置 \(i ...