本篇并不适合初学者阅读。

SCC:

1.Tarjan缩点:x回溯前,dfn[x]==low[x]则缩点。

注意:

①sta,in[]标记。

②缩点之后连边可能有重边。

2.应用:

SCC应用范围还是很广的。

基本思路是:Tarjan+topo

DAG是个好东西。

各种判断连通性(传递关系),计数,以及dp转移

感觉90%以上的tarjan都是考SCC

例题:最大半连通子图(这个题注意缩点后的重边)

衍生应用算法:

①2-SAT

②完备匹配的二分图必须边和可行边。

E-DCC

1.Tarjan找桥:x的一个子节点y,dfn[x]<low[y],边就是桥

注意:

①in_edge,对称建边号。不能从in_edge^1出发。但是可以走重边。

然后不经过桥dfs,找E-DCC

2.应用:

①最短路的必经边:建出最短路图,找桥即可。

②例题:poj3694

找出桥边,E-DCC缩点。

对于询问(x,y)x,y不在一个DCC,

找LCA,之后可以往上暴力找路径,干掉桥。

然鹅使用并查集更快。

O(M+N+Qlogn)

V-DCC

1.找割点:dfn[x]<=low[y]不用管重边什么的。

注意:

①搜索树根节点要有两次符合,才是割点。

其实对于割点x,dfn[x]<=low[y]的出点y,这些y一定在不同的DCC中。

缩点:

除了孤立点之外,每个DCC大小至少为2

每个割点属于多个DCC

用栈维护。

如果某个点满足dfn[x]<=low[y]

那么,不断弹出栈顶,直到y弹出。

把这些点和x都放进一个DCC中。(vector存)

可以发现一个x属于多个DCC

缩点的时候,

先把割点设置编号(cnt+1~cnt+tot)cnt是DCC个数

tot是割点个数

循环所有的DCC,循环所有的成员

如果找到割点,就让这个割点和这个DCC连边。

连出一个黑点白点相间的树(黑点可以认为是割点)

例题:

[HNOI2012]矿场搭建

分类讨论即可

KNIGHTS - Knights of the Round Table

性质题,

建立反图。没有仇恨的人连边。

没有出现在任何一个简单奇环中的骑士滚蛋

V-DCC缩点

如果两个骑士DCC不同,一定不能同时出席。(否则在一个奇环中的话,那么两个DCC可以合并。矛盾)

如果一个DCC中有奇环,那么DCC中的所有骑士都可以被一个奇环包含。(可以构造)

综上,一个骑士被包含,因为不能和其他DCC合作,所以必须当且仅当自己的DCC中有奇环

Tarjan+二分图染色判断奇环

代码:

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define numb (ch^'0')
using namespace std;
typedef long long ll;
namespace Miracle{
const int N=;
const int M=1e6+;
bool hate[N][N];
int n,m;
void rd(int &x){
char ch;x=;
while(!isdigit(ch=getchar()));
for(x=numb;isdigit(ch=getchar());x=x*+numb);
}
struct node{
int nxt,to;
}e[*M];
int cnt,hd[N];
void add(int x,int y){
e[++cnt].nxt=hd[x];
e[cnt].to=y;
hd[x]=cnt;
}
bool cut[N];
bool has[N];//for cut
vector<int>mem[N];
int rt;
int be[N];
int sta[N],top;
int dfn[N],low[N];
int df;
int dcc;
void tarjan(int x){
sta[++top]=x;
low[x]=dfn[x]=++df;
bool fl=false;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to;
if(!dfn[y]){
tarjan(y);
low[x]=min(low[x],low[y]);
if(dfn[x]<=low[y]){
++dcc;
mem[dcc].clear();
if(fl||x!=rt) cut[x]=;
fl=true;
int z;
do{
z=sta[top--];
be[z]=dcc;
mem[dcc].push_back(z);
}while(z!=y);
be[x]=dcc;
mem[dcc].push_back(x);
}
}
else low[x]=min(low[x],dfn[y]);
}
}
int c[N];
bool bla;
bool ok[N];
void che(int x,int las,int id){
// cout<<" che "<<x<<endl;
c[x]=las;
for(reg i=hd[x];i;i=e[i].nxt){
int y=e[i].to; if(be[y]!=id) continue;
// cout<<" goto "<<y<<endl;
if(!c[y]){
che(y,-las,id);
}
else if(c[y]==c[x]) bla=false;
//if(!fl) return false;
}
//return fl;
}
void clear(){
memset(hate,,sizeof hate);
memset(cut,,sizeof cut);
memset(hd,,sizeof hd);cnt=;
memset(dfn,,sizeof dfn);df=;
memset(ok,,sizeof ok);
dcc=;
memset(c,,sizeof c);
memset(has,,sizeof has);
memset(be,,sizeof be);
}
int main(){
while()
{
scanf("%d%d",&n,&m);int x,y;
if(n==&&m==) break;
clear();
for(reg i=;i<=m;++i){
rd(x);rd(y);
hate[x][y]=;
}
for(reg i=;i<=n;++i){
for(reg j=i+;j<=n;++j){
if(!hate[i][j]){
add(i,j);add(j,i);
}
}
}
for(reg i=;i<=n;++i){
if(!dfn[i]) rt=i,top=,tarjan(i);
}
// cout<<" dcc "<<dcc<<endl;
// for(int i=1;i<=n;++i){
// cout<<i<<" : "<<cut[i]<<" "<<be[i]<<endl;
// }cout<<endl;
for(reg i=;i<=dcc;++i){
// cout<<" i---------- "<<i<<endl;
memset(c,,sizeof c);
for(reg j=;j<mem[i].size();++j){
// cout<<" mem "<<mem[i][j]<<endl;
be[mem[i][j]]=i;
}
bla=true;
che(mem[i][],,i);
// cout<<" bla "<<bla<<endl;
if(!bla){
for(reg j=;j<mem[i].size();++j){
ok[mem[i][j]]=;
}
}
} int ans=n;
for(reg i=;i<=n;++i){
ans-=ok[i];
}
printf("%d\n",ans);
}
return ;
} }
int main(){
Miracle::main();
return ;
} /*
Author: *Miracle*
Date: 2018/11/6 7:40:18
*/

附赠福利:

欧拉回路:

void dfs(int x){

for(each son)
if(!vis[i]){

vis[i]=vis[i^1]=1;

dfs(e[i].to)
}

sta[++top]=x;

}

然后sta倒着输出即可。

至于每个点访问多次,可以弧优化减少枚举。

[学习笔记]Tarjan&&欧拉回路的更多相关文章

  1. [学习笔记]tarjan求割点

    都口胡了求割边,就顺便口胡求割点好了QAQ 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访问,并在回溯后更新 2.如果某个邻接点已被访问过,则更新 对于当前 ...

  2. [学习笔记]tarjan求割边

    上午打模拟赛的时候想出了第三题题解,可是我不会求割边只能暴力判割边了QAQ 所以,本文介绍求割边(又称桥). 的定义同求有向图强连通分量. 枚举当前点的所有邻接点: 1.如果某个邻接点未被访问过,则访 ...

  3. 学习笔记--Tarjan算法之割点与桥

    前言 图论中联通性相关问题往往会牵扯到无向图的割点与桥或是下一篇博客会讲的强连通分量,强有力的\(Tarjan\)算法能在\(O(n)\)的时间找到割点与桥 定义 若您是第一次了解\(Tarjan\) ...

  4. [学习笔记] Tarjan算法求桥和割点

    在之前的博客中我们已经介绍了如何用Tarjan算法求有向图中的强连通分量,而今天我们要谈的Tarjan求桥.割点,也是和上篇有博客有类似之处的. 关于桥和割点: 桥:在一个有向图中,如果删去一条边,而 ...

  5. [学习笔记] Tarjan算法求强连通分量

    今天,我们要探讨的就是--Tarjan算法. Tarjan算法的主要作用便是求一张无向图中的强连通分量,并且用它缩点,把原本一个杂乱无章的有向图转化为一张DAG(有向无环图),以便解决之后的问题. 首 ...

  6. $tarjan$简要学习笔记

    $QwQ$因为$gql$的$tarjan$一直很差所以一直想着要写个学习笔记,,,咕了$inf$天之后终于还是写了嘻嘻. 首先说下几个重要数组的基本定义. $dfn$太简单了不说$QwQ$ 但是因为有 ...

  7. Tarjan的学习笔记 求割边求割点

    博主图论比较弱,搜了模版也不会用... 所以决心学习下tarjan算法. 割点和割边的概念不在赘述,tarjan能在线性时间复杂度内求出割边. 重要的概念:时间戟,就是一个全局变量clock记录访问结 ...

  8. 仙人掌&圆方树学习笔记

    仙人掌&圆方树学习笔记 1.仙人掌 圆方树用来干啥? --处理仙人掌的问题. 仙人掌是啥? (图片来自于\(BZOJ1023\)) --也就是任意一条边只会出现在一个环里面. 当然,如果你的图 ...

  9. OI知识点|NOIP考点|省选考点|教程与学习笔记合集

    点亮技能树行动-- 本篇blog按照分类将网上写的OI知识点归纳了一下,然后会附上蒟蒻我的学习笔记或者是我认为写的不错的专题博客qwqwqwq(好吧,其实已经咕咕咕了...) 基础算法 贪心 枚举 分 ...

随机推荐

  1. Python的scrapy之爬取妹子图片

    闲来无事,做的一个小爬虫项目 爬虫主程序: import scrapy from ..items import MeiziItem class MztSpider(scrapy.Spider): na ...

  2. 学习python第一天 pycharm设置

    print(“hello,world”) pycharm设置 1. 选择python 解析器,目的是确定pycharm 的运行环境. 方法: File-->Settings-->Proje ...

  3. go学习笔记-结构体

    结构体 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合 定义 格式 type struct_variable_type struct { member definition; member ...

  4. python2.7入门---文件I/O&简单用户交互

        这篇文章开始之前,我们先来看下python中的输出方法.最简单的输出方法是用print语句,你可以给它传递零个或多个用逗号隔开的表达式.此函数把你传递的表达式转换成一个字符串表达式,并将结果写 ...

  5. 【python3.X】python练习笔记[1]

    ##三位数水仙花 ##方法一,小于指定数字的水仙花数 x=eval(input()) a,b,c = 0,0,0 for i in range (100,x,1): a=i%10 b=i//100 c ...

  6. Android 数据库 ANR的例子

    android 开启事务之后,在其他线程是不能进行增删改查操作的.例子如下: 首先,一个线程里面去开启事务,里面对数据库的任何操作都没有. DBAdapter.getInstance().beginT ...

  7. 【WPF】 布局篇

    [WPF] 布局篇 一. 几个常用且至关重要的属性 1. Width,Height : 设置窗体,控件宽高. 这里注意,WPF是自适应的, 所以把这2个属性设置 Auto, 则控件宽高会自动改变. 2 ...

  8. Qt Qwdget 汽车仪表知识点拆解7 图像绘制,旋转

    先贴上效果图,注意,没有写逻辑,都是乱动的 看下最中心的指针旋转,这里使用的QPainter的绘制函数 要显示复杂的效果,需要分层 void Widget::draw_number_pointer() ...

  9. CentOS环境配置Hadoop(一)

    配置Linux开发环境(hadoop-2.6.4) 一.准备工具 VMware-workstation-10.0.1注册机 CentOS-6.5-x86_64-bin-DVD1 jdk-7u79-li ...

  10. 解决EasyUI DataGrid删除行失败的方法

    笔者最近在做一个项目的后台,用到了EasyUI的datagrid控件,并开启了行内编辑功能,实际上也就是使用了edatagird这个空间,引用了edatagrid.js,一切似乎都做的顺风顺水,添加数 ...