强连通分量——tarjan ->缩点
2017-02-24 11:49
337 查看
对于一些题目,我们找出强连通分量后,就会变得非常简单=v=+
首先介绍强连通:
对于一个有向图,每一对点(x,y)都可以相互到达,则称之为强连通图。
而一个有向图中的极大强连通子图,就称为强连通分量
(注:极大的意思就是说不能再往这个子图中添加点,即当前情况下的最大子图
(强连通都是:环,环套环,环套环套环……
接下来就是求出强连通分量:这里只介绍tarjan算法
定义时间戳dfn[i]表示i是第几个被访问到的节点。
定义返祖数组low[i]表示本块强连通分量中最早被访问的节点的时间
进行深搜,把路径上所有的点压入一个栈中。
那么什么时候弹出?
当一个强连通分量中所有点都被遍历的时候。一个最显而易见的条件:回溯到强连通分量最早被访问的节点。
根据low和dfn的定义,我们可以知道当low[x]==dfn[x]时,我们得到了一个包含x的强连通分量,此时就可以把x到栈顶的所有元素弹出并记录。
那么low[x]如何更新?
① 子节点回溯得到
② 访问到一个已被访问且未被弹出的点
tarjan-dfs部分
所谓tarjan缩点,就是把整个强连通分量当作一个点来进行处理。
显然得到一个性质,缩点后的图不存在环。
下面以 bzoj1051/luogu2341 HAOI2006 受欢迎的牛为例
传送门
这道题的大意就是说有多少头牛被其他所有的牛喜欢,喜欢具有传递性。
乍一看。。。floyd传递闭包?
再一看数据- -
行吧,算我输
经过观察可以发现,我们如果把他们的关系绘成图有以下性质
① 一个强连通子图中所有奶牛都相互喜欢
② 若强连通子图A中有奶牛喜欢强连通子图B中的奶牛,则所有A中奶牛都喜欢所有B中奶牛
那么仔细思考一下,如果我们通过tarjan缩点,把整个图变成有向无环图,是不是就成了一道水题?
因为无环,所有要被所有奶牛崇拜,则这个强连通分量不会有边连到其他的强连通分量,否则就会构成环,即出度为0。
朴素的想法,如果一个强连通分量的入度=分量总数-1,并且出度=0,则满足条件。
但是如果动下脑子,,就可以想到一个巧妙的办法:
当出度为0的点>1个,则 入度=分量总数-1 条件绝对不成立
答案为0
如果出度为0的点=0个 则 出度=0 条件绝对不成立
答案为0
那么显然,如果答案要不为0,出度为0的点=1个!
答案即为这个点的权值(即缩成这个点的强连通分量所包含节点的数量)
CODE:
首先介绍强连通:
对于一个有向图,每一对点(x,y)都可以相互到达,则称之为强连通图。
而一个有向图中的极大强连通子图,就称为强连通分量
(注:极大的意思就是说不能再往这个子图中添加点,即当前情况下的最大子图
(强连通都是:环,环套环,环套环套环……
接下来就是求出强连通分量:这里只介绍tarjan算法
定义时间戳dfn[i]表示i是第几个被访问到的节点。
定义返祖数组low[i]表示本块强连通分量中最早被访问的节点的时间
进行深搜,把路径上所有的点压入一个栈中。
那么什么时候弹出?
当一个强连通分量中所有点都被遍历的时候。一个最显而易见的条件:回溯到强连通分量最早被访问的节点。
根据low和dfn的定义,我们可以知道当low[x]==dfn[x]时,我们得到了一个包含x的强连通分量,此时就可以把x到栈顶的所有元素弹出并记录。
那么low[x]如何更新?
① 子节点回溯得到
② 访问到一个已被访问且未被弹出的点
tarjan-dfs部分
inline void dfs(int x) { dfn[x]=low[x]=++index; sta[++top]=x; ins[x]=1; for(int i=f[x];i;i=next[i]) { int t=poi[i]; if(!dfn[t]) { dfs(t);low[x]=min(low[x],low[t]);} else if(ins[t]) low[x]=min(low[x],low[t]); } if(dfn[x]==low[x]) { while(1) { cnt++; int t=sta[top]; top--; ins[t]=0; lin[t]=cnt; XXXXXXXXX(依题目决定) if(t==x) break; } } }
所谓tarjan缩点,就是把整个强连通分量当作一个点来进行处理。
显然得到一个性质,缩点后的图不存在环。
下面以 bzoj1051/luogu2341 HAOI2006 受欢迎的牛为例
传送门
这道题的大意就是说有多少头牛被其他所有的牛喜欢,喜欢具有传递性。
乍一看。。。floyd传递闭包?
再一看数据- -
行吧,算我输
经过观察可以发现,我们如果把他们的关系绘成图有以下性质
① 一个强连通子图中所有奶牛都相互喜欢
② 若强连通子图A中有奶牛喜欢强连通子图B中的奶牛,则所有A中奶牛都喜欢所有B中奶牛
那么仔细思考一下,如果我们通过tarjan缩点,把整个图变成有向无环图,是不是就成了一道水题?
因为无环,所有要被所有奶牛崇拜,则这个强连通分量不会有边连到其他的强连通分量,否则就会构成环,即出度为0。
朴素的想法,如果一个强连通分量的入度=分量总数-1,并且出度=0,则满足条件。
但是如果动下脑子,,就可以想到一个巧妙的办法:
当出度为0的点>1个,则 入度=分量总数-1 条件绝对不成立
答案为0
如果出度为0的点=0个 则 出度=0 条件绝对不成立
答案为0
那么显然,如果答案要不为0,出度为0的点=1个!
答案即为这个点的权值(即缩成这个点的强连通分量所包含节点的数量)
CODE:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> using namespace std; bool ins[10001]; int index=0,top=0,cnt=0,n,m; int sta[10001],dfn[10001],low[10001],poi[100001],next[100001],f[10001],lin[10001],x[50001],y[50001],num[10001],vis[10001],cant[10001]; inline void add(int x,int y) { poi[++cnt]=y;next[cnt]=f[x];f[x]=cnt; } inline void dfs(int x) { dfn[x]=low[x]=++index; sta[++top]=x; ins[x]=1; for(int i=f[x];i;i=next[i]) { int t=poi[i]; if(!dfn[t]) { dfs(t);low[x]=min(low[x],low[t]);} else if(ins[x]) low[x]=min(low[x],low[t]); } if(dfn[x]==low[x]) { while(1) { int t=sta[top]; top--; ins[t]=0; lin[t]=x; num[x]++; vis[x]=1; if(t==x) break; } } } inline void out() { for(int i=1;i<=m;i++) if(lin[x[i]]!=lin[y[i]]) cant[lin[x[i]]]=1; int hh=0,tx=-1; for(int i=1;i<=n;i++) if(!cant[i]&&vis[i]) { tx=i; hh++; if(hh==2) { printf("0\n"); return; } } if(tx==-1) {printf("0\n");return;} printf("%d\n",num[tx]); } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) { scanf("%d%d",&x[i],&y[i]); add(x[i],y[i]); } for(int i=1;i<=n;i++) { if(!dfn[i]) dfs(i); } out(); }
相关文章推荐
- The King’s Problem(tarjan求强连通分量缩点+匈牙利求有向无环图的最小路径覆盖)
- 强连通分量,Tarjan,缩点(Network of Schools,POJ 1236)
- -----tarjan强连通分量缩点-hdu 5934 -Bomb
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(最近公共祖先)
- 强连通分量及缩点tarjan算法解析
- Tarjan求强连通分量,缩点
- BZOJ 1179: [Apio2009]Atm Tarjan强连通分量缩点,SPFA,DP
- 51nod 1456 小K的技术(Tarjan强连通分量缩点,并查集)
- poj 2186 Popular Cows(Tarjan,强连通分量缩点)
- [笔记]关于tarjan求连通分量 & 缩点
- 由 USACO2003 Popular Cows[受欢迎的奶牛] 认识 Tarjan 求强连通分量并缩点
- 连通分量模板:tarjan: 求割点 && 桥 && 缩点 && 强连通分量 && 双连通分量 && LCA(近期公共祖先)
- POJ 1236 Network Of Schools ( tarjan求强连通分量 + 缩点成DAG图 )
- Tarjan求强连通分量 缩点
- 【日常学习】【强连通分量tarjan缩点】codevs1611 抢掠计划题解
- Network of Schools POJ - 1236 tarjan强连通分量缩点
- Tarjan求强连通分量
- UVALive 4262——Trip Planning——————【Tarjan 求强连通分量个数】
- 上白泽慧音 题解 ---- tarjan求强连通分量
- Tarjan求强连通分量