强连通分量(Kosaraju)
//P2002解题思路:
//先求SCC,缩点后,转换为DAG(有向无环图)
//在DAG上统计入度为0的scc数量即可
//Kosaraju时间复杂度:O(N+E)
//两次DFS,2N,图的转置E,共2N+E
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn=500010;
struct edge{ int t; edge *nxt; edge(int to, edge * next){ t=to, nxt=next; } };
edge * h1[maxn], * h2[maxn]; //h2是反图
void add1(int u, int v){ h1[u]=new edge(v, h1[u]); }
void add2(int u, int v){ h2[u]=new edge(v, h2[u]); }
int n, m, v[maxn], st[maxn], st_k, sccno[maxn], scc_cnt, scc_indegree[maxn];
void dfs1(int x)
{
v[x]=1;
for(edge * p=h1[x]; p; p=p->nxt) if(!v[p->t]) dfs1(p->t);
st[++st_k]=x;
}
void dfs2(int x)
{
v[x]=1;
sccno[x]=scc_cnt;
for(edge * p=h2[x]; p; p=p->nxt) if(!v[p->t]) dfs2(p->t);
}
void kosaraju()
{
for(int i=1; i<=n; i++) if(!v[i]) dfs1(i);
memset(v, 0, sizeof(v));
for(int i=st_k; i>=1; i--)
if(!v[st[i]]) scc_cnt++, dfs2(st[i]);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i=1, b, e; i<=m; i++)
{
scanf("%d%d", &b, &e);
if(b!=e) add1(b, e), add2(e, b); //去除自环
}
kosaraju();
for(int i=1; i<=n; i++) //统计每个scc的入度
for(edge *p=h1[i]; p; p=p->nxt)
if(sccno[i]!=sccno[p->t]) scc_indegree[sccno[p->t]]++; //起点和终点不在一个scc中才统计入度
int ans=0;
for(int i=1; i<=scc_cnt; i++) if(!scc_indegree[i]) ans++; //统计入度为0的scc的个数
printf("%d\n", ans);
return 0;
}
强连通分量(Kosaraju)的更多相关文章
- POJ 2186 Popular Cows(强连通分量Kosaraju)
http://poj.org/problem?id=2186 题意: 一个有向图,求出点的个数(任意点可达). 思路: Kosaraju算法的第一次dfs是后序遍历,而第二次遍历时遍历它的反向图,从标 ...
- 有向图的强连通分量——kosaraju算法
一.前人种树 博客:Kosaraju算法解析: 求解图的强连通分量
- 模板 - 图论 - 强连通分量 - Kosaraju算法
这个算法是自己实现的Kosaraju算法,附带一个缩点,其实缩点这个跟Kosaraju算法没有什么关系,应该其他的强连通分量算法计算出每个点所属的强连通分量之后也可以这样缩点. 算法复杂度: Kosa ...
- 模板 - 强连通分量 - Kosaraju
Kosaraju算法 O(n+m) vector<int> s; void dfs1(int u) { vis[u] = true; for (int v : g[u]) if (!vis ...
- 强连通分量-----Kosaraju
芝士: 有向图强连通分量在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connect ...
- 图的强连通分量-Kosaraju算法
输入一个有向图,计算每个节点所在强连通分量的编号,输出强连通分量的个数 #include<iostream> #include<cstring> #include<vec ...
- 强连通分量Kosaraju
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #i ...
- 有向图强连通分量的Tarjan算法和Kosaraju算法
[有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...
- 图论-求有向图的强连通分量(Kosaraju算法)
求有向图的强连通分量 Kosaraju算法可以求出有向图中的强连通分量个数,并且对分属于不同强连通分量的点进行标记. (1) 第一次对图G进行DFS遍历,并在遍历过程中,记录每一个点的退出顺序 ...
- POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】
Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 23445 Accepted: 9605 Des ...
随机推荐
- [20190416]完善shared latch测试脚本2.txt
[20190416]完善shared latch测试脚本2.txt --//昨天测试shared latch,链接:http://blog.itpub.net/267265/viewspace-264 ...
- Win10 Ubuntu子系统运行32bit Linux原生程序
本文主要描述的是:解决 Win10 Ubuntu子系统中运行 32bit Linux原生程序 报错 Exec format error . 问题来源于 在 Win10 Ubuntu子系统中运行 ...
- LeetCode算法题-Find Smallest Letter Greater Than Target(Java实现)
这是悦乐书的第306次更新,第326篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第175题(顺位题号是744).给定一个仅包含小写字母的有序字符数组,并给定目标字母目标 ...
- html页面打开ie浏览器默认打开最高版本
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
- ZooKeeper 之快速入门
-----------------破镜重圆,坚持不懈! 1. 概述 Zookeeper是Hadoop的一个子项目,它是分布式系统中的协调系统,可提供的服务主要有:配置服务.名字服务.分布式同步.组服务 ...
- c# 串口SerialPort
创建SerialPortFun类 using System; using System.Collections.Generic; using System.Linq; using System.Tex ...
- 【问题解决方案】ImportError: No module named 'pygal'
<Python编程:从入门到实践>一书,第二个项目-可视化,第四节用到pygal 安装部分用 'python -m pip install pygal==1.7' 安装,但使用时仍然报错 ...
- http请求方式和传递数据类型
HTTP(HyperText Transfer Protocol)是一套计算机通过网络进行通信的规则. GET,通过请求URI得到资源 POST,用于添加新的内容 PUT用于修改某个内容 DELETE ...
- html表单的方便操作
//表单阻止复制粘贴 <input class="pass" type="text" oncopy="return false" on ...
- Singleton多种实现方式的在多线程情况下的优缺点
一.饿汉式 缺点:不能懒加载 // 不能懒加载 public class SingletonObject1 { private static final SingletonObject1 instan ...