强连通分量(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 ...
随机推荐
- 为什么CynosDB叫真正的云原生数据库?
本文由腾讯云数据库发表 注:本文摘自2018年11月22日腾讯云数据库CynosDB新品发布会的演讲实录.随着互联网信息的发展,大家也对云这个词汇也不是特别陌生了,作为全球首选的云服务厂商之一的腾讯云 ...
- Visual Studio Code自定义快捷键(eclipse习惯)
左下角设置按钮 -> Keyboard Shortcuts -> keybindings.json. [ { "key": "alt+/", &qu ...
- Linux(CentOS7)yum安装卸载命令,离线下载安装包
一.Linux版本 二.yum安装 比如安装vim编辑器,y是自动应答,即默认一路确认,不用中途确认 yum install -y vim 三.yum卸载 比如卸载掉刚刚安装的vim yum eras ...
- mysql下载安装及常见问题
1.下载MySql 官网下载地址:https://dev.mysql.com/downloads/mysql/ 2.安装 如果下载的是zip的,直接解压目录即可,我的解压目录时:C:\mysql\my ...
- 一个简易的kmp教学并给出java实现
简单介绍一下问题 给定source字符串,找出target字符串出现的首位 例如 source 为“abddabddabc” target 为 “abddabc” 从第一位开始比较 |a b d ...
- 【spring源码分析】IOC容器初始化(九)
前言:上篇文章末尾提到createBeanInstance方法中使用工厂方法实例化Bean对象,本文将对该方法进行分析. AbstractAutowireCapableBeanFactory#inst ...
- idea 右键无java class选项
项目中新建module之后,要在该目录下新增java Class文件,右键——>New发现无Java Class选项. File –Project Structure或者ctrl+alt+shi ...
- 逆向工程核心原理-IA-32寄存器
IA-32由四类寄存器组成:通用寄存器,段寄存器,程序状态与控制寄存器,指令指针寄存器. 通用寄存器:用于传送和暂存数据,也可参与算数逻辑运算,并保存运算结果. EAX(0-31) 32位 ...
- promise async await使用
1.Promise (名字含义:promise为承诺,表示其他手段无法改变) Promise 对象代表一个异步操作,其不受外界影响,有三种状态: Pending(进行中.未完成的) Resolved( ...
- HTML之表单
目录 表单的结构 get方式与post方式 输入 单行文本输入框 提交按钮和重置按钮 密码输入框 复选框 单选按钮 图像按钮 文本选择输入框 隐藏框 多行文本输入框 下拉列表框 新增输入元素 新增其他 ...