今天学了一个强连通分量,用tarjan做。北京之前讲过,今天讲完和之前一样,没有什么进步。上课没听讲,只好回来搞,这里安利一个博客:链接

https://blog.csdn.net/qq_34374664/article/details/77488976

讲一下我自己的体会吧,其实就是维护一个栈,然后树上跑dfs,每个节点存两个值:dn和low,dn代表dfs的顺序(时间),low代表的是他可以连通的最小的节点。

模拟一下,然后就会发现,其实整个算法就是模拟了一下将每个点压入栈。然后遇到之前在栈里的元素,向后弹出到这一位就行了。

洛谷板子题:链接

直接上代码,很好懂。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
int m,n,len = ,stc[];
int ri = ,tot = ,ans = ;
int num[];
struct node{
int l,r,nxt;
}a[];
int low[],lst[];
int dn[];
int chu[];
bool vis[];
int add(int x,int y)
{
a[++len].l = x;
a[len].r = y;
a[len].nxt = lst[x];
lst[x] = len;
chu[x]++;
}
void dfs(int x)
{
dn[x] = low[x] = ++tot;
stc[++ri] = x;
vis[x] = ;
for(int k = lst[x];k;k = a[k].nxt)
{
int y = a[k].r;
if(!dn[y])
{
dfs(y);
low[x] = min(low[x],low[y]);
}
else if(vis[y])
{
low[x] = min(low[x],dn[y]);
}
}
if(low[x] == dn[x])
{
ans ++;
int v;
do
{
num[ans]++;
vis[stc[ri]] = ;
v = stc[ri--];
}
while(x != v);
}
}
int main()
{
memset(vis,,sizeof(vis));
scanf("%d%d",&n,&m);
int x,y;
for(int i = ;i <= m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i = ;i <= n;i++)
if(dn[i] == )
{
dfs(i);
}
// cout<<ans<<endl;
tot = ;
for(int i = ;i <= ans;i++)
{
if(num[i] > )
{
tot++;
}
}
printf("%d\n",tot);
return ;
}

洛谷日推了一道题,也是板子,写一下:

每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶

牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜

欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你

算出有多少头奶牛可以当明星。
输入输出格式
输入格式:  第一行:两个用空格分开的整数:N和M  第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B 输出格式:  第一行:单独一个整数,表示明星奶牛的数量 输入输出样例
输入样例#: 复制 输出样例#: 复制

直接上代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(),c < '' || c > '')
if(c == '-' ) op = ;
x = c - '';
while(c = getchar(),c >= '' && c <= '')
x =x * + c - '';
if(op)
x = -x;
}
int lst[],dfn[],low[],n,m,tot = ,str[],top = ,vis[];
int num[],chu[],col[],len,ans;
struct node{
int l,r,nxt;
}a[];
void add(int x,int y)
{
a[++len].l = x;
a[len].r = y;
a[len].nxt = lst[x];
lst[x] =len;
// chu[x]++;
}
void tarjan(int x)
{
dfn[x] = low[x] = ++tot;
str[++top] = x;
vis[x] = ;
for(int k = lst[x];k;k = a[k].nxt)
{
int y = a[k].r;
if(!dfn[y])
{
tarjan(y);
low[x] = min(low[x],low[y]);
}
else if(vis[y])
{
low[x] = min(low[x],dfn[y]);
}
}
if(low[x] == dfn[x])
{
ans++;
int v;
do
{
num[ans]++;
vis[str[top]] = ;
v = str[top--];
col[v] = ans;
}
while(x != v);
}
}
int main()
{
read(n);read(m);
for(int i = ;i <= m;i++)
{
int x,y;
read(x);read(y);
add(x,y);
}
for(int i = ;i <= n;i++)
{
if(dfn[i] == )
{
tarjan(i);
}
}
for(int i = ;i <= n;i++)
{
for(int k = lst[i];k;k = a[k].nxt)
{
if(col[a[k].l] != col[a[k].r])
{
chu[col[a[k].l]]++;
}
}
}
int tot= ,f;
for(int i = ;i <= ans;i++)
{
if(chu[i] == )
{
tot++;
f = i;
}
if(tot >= )
{
puts("");
return ;
}
}
printf("%d\n",num[f]);
return ;
}

强连通分量--tarjan算法的更多相关文章

  1. 有向图强连通分量Tarjan算法

    在https://www.byvoid.com/zhs/blog/scc-tarjan中关于Tarjan算法的描述非常好,转述如下: 首先解释几个概念: 有向图强连通分量:在有向图G中,如果两个顶点间 ...

  2. 有向图强连通分量 Tarjan算法

    [有向图强连通分量] 在有向图G中,如果两个顶点间至少存在一条路径,称两个顶点强连通(strongly connected).如果有向图G的每两个顶点都强连通,称G是一个强连通图.非强连通图有向图的极 ...

  3. [有向图的强连通分量][Tarjan算法]

    https://www.byvoid.com/blog/scc-tarjan 主要思想 Tarjan算法是基于对图深度优先搜索的算法,每个强连通分量为搜索树中的一棵子树.搜索时,把当前搜索树中未处理的 ...

  4. 图之强连通、强连通图、强连通分量 Tarjan算法

    原文地址:https://blog.csdn.net/qq_16234613/article/details/77431043 一.解释 在有向图G中,如果两个顶点间至少存在一条互相可达路径,称两个顶 ...

  5. 图论-强连通分量-Tarjan算法

    有关概念: 如果图中两个结点可以相互通达,则称两个结点强连通. 如果有向图G的每两个结点都强连通,称G是一个强连通图. 有向图的极大强连通子图(没有被其他强连通子图包含),称为强连通分量.(这个定义在 ...

  6. 求图的强连通分量--tarjan算法

    一:tarjan算法详解 ◦思想: ◦ ◦做一遍DFS,用dfn[i]表示编号为i的节点在DFS过程中的访问序号(也可以叫做开始时间)用low[i]表示i节点DFS过程中i的下方节点所能到达的开始时间 ...

  7. POJ1236_A - Network of Schools _强连通分量::Tarjan算法

    Time Limit: 1000MS   Memory Limit: 10000K Description A number of schools are connected to a compute ...

  8. poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】

    题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Sub ...

  9. 强连通分量——tarjan算法

    概念: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通.如果有向图G的每两个顶点都强连 ...

随机推荐

  1. Microsoft SQL Server学习(二)--数据库的语法

    关于数据库的语法 创建数据库 样例 名词概念 编写数据库代码的注意事项 关于文件语法 实例代码 关于数据库的语法: 1.创建数据库 create database 数据库名 on primary (主 ...

  2. 在mac上快捷找到nodejs的安装路径

    打开控制台输入 which node ,得到的输出结果就是node安装路径

  3. html5——表单

    type类型 email //输入email格式 tel //手机号码 url //只能输入url格式 number //只能输入数字 search //搜索框 range //范围 滑动条 colo ...

  4. CSS——行内元素的margin与padding

    行内元素: 1.margin:0 20px:只可以定义左右. 2.pading:20px 20px 20px 20px:上下左右都有效 例如span: <!DOCTYPE html> &l ...

  5. 3星|《腾讯产业森林:AI时代的创业密码》:后半部分是较详细的创业指南,前面泛泛介绍腾讯、AI

    腾讯产业森林:AI时代的创业密码 前半部分泛泛介绍腾讯对创业者的支持,腾讯支持的创业项目的案例.AI的一些基本介绍,后半部分是比较详细的写给创业者的各阶段行动与选择的指南. 总体评价3星,有一些参考价 ...

  6. cookie和sessionStorage 、localStorage 对比

    相同点:都存储在客户端 不同点:1.存储大小 cookie数据大小不能超过4k. sessionStorage和localStorage 虽然也有存储大小的限制,但比cookie大得多,可以达到5M或 ...

  7. =new、=null、.clear()、system.gc()的区别

    开发经验告诉我 = new是指向另一个地址空间 =null对象被回收 .clear()对象被清空,但是仍然指向原来的地址空间 这三种方式都并没有真正的清理内存 只有system.gc()是直接清理,但 ...

  8. EAS之校验检查

    先了解一下权限接口类提供的有关权限项检查的方法public boolean hasFunctionPermission(IObjectPK userPK,IObjectPK orgPK,String ...

  9. 原始js表单文本框初始化获取焦点和选中

    发现: 1 使用dom对象.focus() 放在 window.onload 时可以 让这个DOM对象获取焦点. 2 使用DOM对象.select() 可以选中文本框中的文字. 3 不要加上on  , ...

  10. Linux下源码安装Peach-2.3.8教程

    在peach文件夹下运行 python peach.py ./samples/HelloWorld.xml 提示先安装4Suite-XML. 根据提示在dependences文件夹下安装,出现两次错误 ...