由于昨天写计蒜客初赛的一道题,看出了是缩点,但一时忘记了另外一个叫什么s...的算法怎么写了,话说我为什么没有回去翻一下自己的blog然后今天就去学了更实用也更强力的Tarjan

Tarjan的思想其实很简单,就是用时间戳(讲得真TM流弊,其实就是DFS访问到的次序)和栈来搞一下

关于Tarjan的写法,我自己也不是很讲得来,大家可以看一下这篇blog

这里讲一下如何用Tarjan来进行缩点

令我们求出的col[i]表示原图中第i个点是哪个强连通分量中的,则我们可以建出新图,方式如下

for (i=1;i<=n;++i)
for (j=head[i];j!=-1;j=e[j].next)
if (col[i]!=col[e[j].to]) add(col[i],col[e[j].to]);

很玄学?但是它就是正确的,然后我们就得到了缩过点的新图

像有这里有一道模板题:Luogu P3387 【模板】缩点

题意很简单,我们先Tarjan缩点,缩完的点的点权就是它这个强连通分量中的所有点的点权和

然后就是一个DAG(有向无环图)了,我们DP,记搜,拓扑排序都可以

这里我还是习惯性的写了BFS的topo

CODE

#include<cstdio>
#include<cstring>
using namespace std;
const int N=1e4+5,M=1e5+5;
struct edge
{
int to,next;
}e[M],ne[M];
int n,m,head[N],nhead[N],a[N],v[N],dfn[N],low[N],stack[N],col[N],dis[N],q[N],ru[N],top,cnt,x,y,tot,sum;
bool vis[N];
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline void add(int x,int y)
{
e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
}
inline void nadd(int x,int y)
{
ne[++cnt].to=y; ne[cnt].next=nhead[x]; nhead[x]=cnt;
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
inline void Tarjan(int now)
{
dfn[now]=low[now]=++tot;
stack[++top]=now; vis[now]=1;
for (register int i=head[now];i!=-1;i=e[i].next)
if (!dfn[e[i].to])
{
Tarjan(e[i].to);
low[now]=min(low[now],low[e[i].to]);
} else
{
if (vis[e[i].to]) low[now]=min(low[now],dfn[e[i].to]);
}
if (dfn[now]==low[now])
{
col[now]=++sum;
v[sum]+=a[now]; vis[now]=0;
while (now!=stack[top])
{
col[stack[top]]=sum;
v[sum]+=a[stack[top]]; vis[stack[top--]]=0;
} --top;
}
}
inline int topo(void)
{
memset(dis,0,sizeof(dis));
register int i; int ans=0;
int H=0,T=0;
for (i=1;i<=sum;++i)
if (!ru[i]) q[++T]=i,dis[i]=v[i],ans=max(dis[i],ans);
while (H<T)
{
int now=q[++H];
for (i=nhead[now];i!=-1;i=ne[i].next)
{
dis[ne[i].to]=max(dis[ne[i].to],dis[now]+v[ne[i].to]);
ans=max(ans,dis[ne[i].to]);
if (!(--ru[ne[i].to])) q[++T]=ne[i].to;
}
}
return ans;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i,j;
memset(head,-1,sizeof(head));
memset(e,-1,sizeof(e));
read(n); read(m);
for (i=1;i<=n;++i)
read(a[i]);
for (i=1;i<=m;++i)
read(x),read(y),add(x,y);
for (i=1;i<=n;++i)
if (!dfn[i]) Tarjan(i);
memset(nhead,-1,sizeof(head));
memset(ne,-1,sizeof(e)); cnt=0;
for (i=1;i<=n;++i)
for (j=head[i];j!=-1;j=e[j].next)
if (col[i]!=col[e[j].to]) nadd(col[i],col[e[j].to]),++ru[col[e[j].to]];
printf("%d",topo());
return 0;
}

Tarjan&&缩点简析的更多相关文章

  1. 简析.NET Core 以及与 .NET Framework的关系

    简析.NET Core 以及与 .NET Framework的关系 一 .NET 的 Framework 们 二 .NET Core的到来 1. Runtime 2. Unified BCL 3. W ...

  2. 简析 .NET Core 构成体系

    简析 .NET Core 构成体系 Roslyn 编译器 RyuJIT 编译器 CoreCLR & CoreRT CoreFX(.NET Core Libraries) .NET Core 代 ...

  3. hihoCoder 1185 连通性·三(Tarjan缩点+暴力DFS)

    #1185 : 连通性·三 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 暑假到了!!小Hi和小Ho为了体验生活,来到了住在大草原的约翰家.今天一大早,约翰因为有事要出 ...

  4. POJ 1236 Network of Schools(Tarjan缩点)

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16806   Accepted: 66 ...

  5. King's Quest —— POJ1904(ZOJ2470)Tarjan缩点

    King's Quest Time Limit: 15000MS Memory Limit: 65536K Case Time Limit: 2000MS Description Once upon ...

  6. RecycleView + CardView 控件简析

    今天使用了V7包加入的RecycleView 和 CardView,写篇简析. 先上效果图: 原理图: 这是RecycleView的工作原理: 1.LayoutManager用来处理RecycleVi ...

  7. 【BZOJ-2438】杀人游戏 Tarjan + 缩点 + 概率

    2438: [中山市选2011]杀人游戏 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1638  Solved: 433[Submit][Statu ...

  8. 【BZOJ-1924】所驼门王的宝藏 Tarjan缩点(+拓扑排序) + 拓扑图DP

    1924: [Sdoi2010]所驼门王的宝藏 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 318[Submit][Stat ...

  9. Java Android 注解(Annotation) 及几个常用开源项目注解原理简析

    不少开源库(ButterKnife.Retrofit.ActiveAndroid等等)都用到了注解的方式来简化代码提高开发效率. 本文简单介绍下 Annotation 示例.概念及作用.分类.自定义. ...

随机推荐

  1. Just write about

    创建一个学生对象,存储学生对象,学生对象的数据来源于键盘录入,最后遍历集合. 学生类,集合对象,键盘录入数据并将数据赋值给学生类的成员(可以写成一个方法),调用方法,遍历集合.

  2. Python Django框架笔记(五):模型

    #前言部分来自Django Book (一)    前言 大多数web应用本质上: 1. 每个页面都是将数据库的数据以HTML格式进行展现. 2. 向用户提供修改数据库数据的方法.(例如:注册.发表评 ...

  3. 七牛云A账号数据迁移到B账号下

    1,七牛云A账号下开启空间授权,可以让B账号可以访问A账号下的空间,,授予权限只读即可. 2,下载七牛云命令行工具.(通过命令完成数据迁移) https://dn-devtools.qbox.me/2 ...

  4. PowerDesigner Code和Name设置大写tablespace设置,PK设置

    1,PowerDesigner Code和Name设置大写 tool>MODEL OPTIONS 2.从oracle数据库导出的表结构默认包含了tablespace 删除tablespace方法 ...

  5. 如何使用EditPlus批量删除 带有某个字符的一行

    比如以下五行,我要将带有英文字母a的一行全部批量删除1234551243243123aa244123123981232137aa 2013-04-11 19:32   提问者采纳   我这里是英文版, ...

  6. [技术] OIer的C++标准库 : STL入门

    注: 本文主要摘取STL在OI中的常用技巧应用, 所以可能会重点说明容器部分和算法部分, 且不会讨论所有支持的函数/操作并主要讨论 C++11 前支持的特性. 如果需要详细完整的介绍请自行查阅标准文档 ...

  7. Q矩阵输出

    程序启动时: 1.Q矩阵在InitQX中对角阵赋初值为0.25,GPS卫星数6 2.Q矩阵初值在初始化时由GetBL获得,改变Q对角阵 Q初值第0个卫星 10000000000.000 X初值第0个卫 ...

  8. python spawnv用法

    test.py import os import string def run(program, *args): file = program result = os.spawnv(os.P_WAIT ...

  9. Python csv.md

    csv csv模块可以用于处理从电子表格和数据库导出的数据到带有字段和记录格式的文本文件,通常称为逗号分隔值(csv)格式,因为逗号通常用于分隔记录中的字段. Reading csv.reader(c ...

  10. 死磕nginx系列--nginx服务器做web服务器

    nginx 做静态服务器 HTML页面如下 <!DOCTYPE html> <html lang="en"> <head> <meta c ...