因为最近在学2sat,需要学习前置技能—Tarjan算法,所以花了一天的时间学习这个算法

算法步骤:

1.从一个点开始dfs,并加入栈

2.如果下一个点没有到过,跳到第一步

3.如果下一个点到过,并且在栈中,下一个点到这个点,这一段构成一个回路,也就是可以缩点

具体实现

void dfs(int x)
{
st.push(x); //加入栈
dis[x]=1; //x点在栈中
dfn[x]=low[x]=++te; //dfn用来表示某个点访问过,并且记录初始的low值
for(int i=f[x]; i; i=nex[i])
{
int v=to[i];
if(dfn[v]==0)
{
dfs(v);
low[x]=min(low[x],low[v]); //将一个回路的low改成一样的
}
else if(dis[v]==1)low[x]=min(low[x],low[v]); //下一个点在栈中,那么找到一个回路,但是可能是嵌套回路,所以取最小low
}
if(dfn[x]==low[x]) //表示x点的初始值没有被改变,构成一个强连通分量
{
while(st.size())
{
int g=st.top();
st.pop();
dis[g]=0;
id[g]=x; //用x命名强连通分量
if(g==x)break; //代表g是强连通分量的最后一个数
}
}
}

题目:poj2186

题解:先缩点,然后构成一个新的图,找到出度为一的一个被缩过的点,返回这个点的数量,如果有1个以上被缩过的点出度为0,那么返回0

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <stack>
using namespace std;
#define ll long long
const int maxn=1e4+;
const int maxm=5e4+;
int f[maxn],nex[maxm],to[maxm],cnt,ot[maxm];
int dfn[maxn],low[maxn],id[maxn],te;
vector<int>ve;
stack<int>st;
int ma[maxn];
bool dis[maxn];
void add(int a,int b)
{
cnt++;
to[cnt]=b;
nex[cnt]=f[a];
f[a]=cnt;
ot[cnt]=a;
}
void dfs(int x)
{
st.push(x);
dis[x]=;
dfn[x]=low[x]=++te;
for(int i=f[x]; i; i=nex[i])
{
int v=to[i];
if(dfn[v]==)
{
dfs(v);
low[x]=min(low[x],low[v]);
}
else if(dis[v]==)low[x]=min(low[x],low[v]);
}
if(dfn[x]==low[x])
{
ve.push_back(x);
while(st.size())
{
int g=st.top();
st.pop();
dis[g]=;
id[g]=x;
if(g==x)break;
}
}
}
int main()
{
int n,m;
scanf("%d %d",&n,&m);
for(int i=; i<=n; i++)id[i]=i;
for(int i=; i<=m; i++)
{
int a,b;
scanf("%d %d",&a,&b);
add(a,b);
}
for(int i=; i<=n; i++)
if(dfn[i]==)dfs(i);
for(int i=; i<=cnt; i++)
{
int a=id[to[i]];
int b=id[ot[i]];
if(a!=b)
ma[b]++;
}
int fla=,num=; for(int i=; i<ve.size(); i++)
{
if(ma[ve[i]]==)num++,fla=ve[i];
}
if(ve.size()==)num=,fla=ve[];
if(num==)
{
int ans=;
for(int i=; i<=n; i++)
if(id[i]==fla)ans++;
printf("%d\n",ans);
}
else
printf("0\n");
return ;
}

Tarjan算法(缩点)的更多相关文章

  1. tarjan算法+缩点--cojs 908. 校园网

    cojs 908. 校园网 ★★   输入文件:schlnet.in   输出文件:schlnet.out   简单对比时间限制:1 s   内存限制:128 MB USACO/schlnet(译 b ...

  2. tarjan算法+缩点:求强连通分量 POJ 2186

    强连通分量:1309. [HAOI2006]受欢迎的牛 ★★   输入文件:cow.in   输出文件:cow.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 每一头牛 ...

  3. POJ 1236 Network of Schools (tarjan算法+缩点)

    思路:使用tarjan求强连通分量并进行缩点,判断所有入度为0的点,这个点就是必须要给予文件的点,分别计算出度,入度为零的点的个数,取二者的最大值就是把这个图变成强连通需要加的边数. 一个取值需要讨论 ...

  4. POJ - 2553 tarjan算法+缩点

    题意: 给你n个点,和m条单向边,问你有多少点满足(G)={v∈V|∀w∈V:(v→w)⇒(w→v)}关系,并把这些点输出(要注意的是这个关系中是蕴含关系而不是且(&&)关系) 题解: ...

  5. tarjan算法(求强连通子块,缩点)

    tarjan算法求图中的强连通子图的个数. #include<iostream> #include<stack> #include<queue> #include& ...

  6. poj2186tarjan算法缩点求出度

    poj2186tarjan算法缩点求出度 自己打一遍第一题,入门啦,入门啦 题目还算简单,多头牛,给你仰慕关系(可传递),问你最后有没有牛被所有的牛仰慕 根据关系可以建图,利用tarjan算法缩点处理 ...

  7. Tarjan算法求割点

    (声明:以下图片来源于网络) Tarjan算法求出割点个数 首先来了解什么是连通图 在图论中,连通图基于连通的概念.在一个无向图 G 中,若从顶点i到顶点j有路径相连(当然从j到i也一定有路径),则称 ...

  8. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  9. tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)

    这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...

随机推荐

  1. Linux进程调度器的设计--Linux进程的管理与调度(十七)

    1 前景回顾 1.1 进程调度 内存中保存了对每个进程的唯一描述, 并通过若干结构与其他进程连接起来. 调度器面对的情形就是这样, 其任务是在程序之间共享CPU时间, 创造并行执行的错觉, 该任务分为 ...

  2. c/c++ 标准库 pair 介绍

    标准库 pair 介绍 问题:map里的元素由key和value组成,这个key和value的组合是什么类型呢??? 答案:pair类型 pair介绍: 它是模板 有2个公有成员可供访问. first ...

  3. iOS 验证码按钮倒计时

    在app 注册或者登录 需要验证码的地方.为了避免短时间内刷验证码.往往会加上一层验证. 倒计时结束后.可以重新获取! 代码实现如下: // _CountdownTime 倒计时总时间: //_tim ...

  4. 二、selenium 安装

    selenium的安装所需要的环境: 1.浏览器的安装Firefox 2.JDK的安装(Java开发基础类库)eclipse 一个开发源代码的工具 3.selenium sever 下载.网络状况监视 ...

  5. [Hive_7] Hive 中的 DDL 操作

    0. 说明 DDL(Data Definition Languages)语句:数据定义语言 这些语句定义了不同的数据段.数据库.表.列.索引等数据库对象的定义. 常用的语句关键字主要包括 create ...

  6. 解决 win10 由于磁盘缓慢造成机器迟钝

    关闭 windows 的superfetch服务 建议禁止 superfetch服务: http://www.360quan.com/safe/6946.html 操作: http://jingyan ...

  7. Qt的事件

    Qt的事件机制 事件过滤器: 可以让一个对象侦听拦截另外一个对象的事件. 实现原理: 在所有Qt对象的基类:QObject中有一个 类型为:QObjectList 名字为:eventFilters 的 ...

  8. March 08th, 2018 Week 10th Thursday

    Easy come, easy go. 易得则易失. Easy come, easy go, I finally undestand the phrase through somewhat hard ...

  9. 【English】20190306

    Delivery team交付团队consumption消费[kənˈsʌmpʃən] The Consulting Delivery team is focused on delivering va ...

  10. yum安装提示Another app is currently holding the yum lock; waiting for it to exit...

    在Linux系统中使用yum安装软件时,提示yum处于锁定状态 Another app is currently holding the yum lock; waiting for it to exi ...