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

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

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

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

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

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

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

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

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

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

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

CODE

  1. #include<cstdio>
  2. #include<cstring>
  3. using namespace std;
  4. const int N=1e4+5,M=1e5+5;
  5. struct edge
  6. {
  7. int to,next;
  8. }e[M],ne[M];
  9. 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;
  10. bool vis[N];
  11. inline char tc(void)
  12. {
  13. static char fl[100000],*A=fl,*B=fl;
  14. return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
  15. }
  16. inline void read(int &x)
  17. {
  18. x=0; char ch=tc();
  19. while (ch<'0'||ch>'9') ch=tc();
  20. while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
  21. }
  22. inline void add(int x,int y)
  23. {
  24. e[++cnt].to=y; e[cnt].next=head[x]; head[x]=cnt;
  25. }
  26. inline void nadd(int x,int y)
  27. {
  28. ne[++cnt].to=y; ne[cnt].next=nhead[x]; nhead[x]=cnt;
  29. }
  30. inline int min(int a,int b)
  31. {
  32. return a<b?a:b;
  33. }
  34. inline int max(int a,int b)
  35. {
  36. return a>b?a:b;
  37. }
  38. inline void Tarjan(int now)
  39. {
  40. dfn[now]=low[now]=++tot;
  41. stack[++top]=now; vis[now]=1;
  42. for (register int i=head[now];i!=-1;i=e[i].next)
  43. if (!dfn[e[i].to])
  44. {
  45. Tarjan(e[i].to);
  46. low[now]=min(low[now],low[e[i].to]);
  47. } else
  48. {
  49. if (vis[e[i].to]) low[now]=min(low[now],dfn[e[i].to]);
  50. }
  51. if (dfn[now]==low[now])
  52. {
  53. col[now]=++sum;
  54. v[sum]+=a[now]; vis[now]=0;
  55. while (now!=stack[top])
  56. {
  57. col[stack[top]]=sum;
  58. v[sum]+=a[stack[top]]; vis[stack[top--]]=0;
  59. } --top;
  60. }
  61. }
  62. inline int topo(void)
  63. {
  64. memset(dis,0,sizeof(dis));
  65. register int i; int ans=0;
  66. int H=0,T=0;
  67. for (i=1;i<=sum;++i)
  68. if (!ru[i]) q[++T]=i,dis[i]=v[i],ans=max(dis[i],ans);
  69. while (H<T)
  70. {
  71. int now=q[++H];
  72. for (i=nhead[now];i!=-1;i=ne[i].next)
  73. {
  74. dis[ne[i].to]=max(dis[ne[i].to],dis[now]+v[ne[i].to]);
  75. ans=max(ans,dis[ne[i].to]);
  76. if (!(--ru[ne[i].to])) q[++T]=ne[i].to;
  77. }
  78. }
  79. return ans;
  80. }
  81. int main()
  82. {
  83. //freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
  84. register int i,j;
  85. memset(head,-1,sizeof(head));
  86. memset(e,-1,sizeof(e));
  87. read(n); read(m);
  88. for (i=1;i<=n;++i)
  89. read(a[i]);
  90. for (i=1;i<=m;++i)
  91. read(x),read(y),add(x,y);
  92. for (i=1;i<=n;++i)
  93. if (!dfn[i]) Tarjan(i);
  94. memset(nhead,-1,sizeof(head));
  95. memset(ne,-1,sizeof(e)); cnt=0;
  96. for (i=1;i<=n;++i)
  97. for (j=head[i];j!=-1;j=e[j].next)
  98. if (col[i]!=col[e[j].to]) nadd(col[i],col[e[j].to]),++ru[col[e[j].to]];
  99. printf("%d",topo());
  100. return 0;
  101. }

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. MVC与单元测试实践之健身网站(一)-项目概述

    前不久刚刚通过租房网站的开发学习了MVC,并随后学习了单元测试相关的基础,现在开始健身网站的开发,该项目将结合MVC与单元测试,在开发实践过程中,趁热打铁,巩固并运用之前的内容. 一 健身网站功能描述 ...

  2. ie8 透明背景不能点击问题

    最近开发网站,需求是三个一屏,1和3只能看见一半,2显示在中间,无箭头按钮. 因为之前写过一个有前后按钮的插件,想着怎么就在这上面改造,故把前后按钮去掉背景,定位在了1和3的位置上来实现点击前后, 发 ...

  3. Web Api通过文件流下载文件到本地实例

    最近项目里面需要和C++的客户端互动,其中一个接口就是需要提供文件下载的接口,保证C++项目调用这个接口的时候能够正常下载文件到本地.参考了一下网上的代码,其原理就是读取服务器上指定路径的文件流,并将 ...

  4. The Downside of MySQL Auto-reconnect

    A few days ago I was doing some cleanup on a passive master database using the MySQL client. I didn’ ...

  5. 常用的 接口访问方法 post 和get

    public string GetFunction(string serviceAddress) { HttpWebRequest request = (HttpWebRequest)WebReque ...

  6. TruncateATable 清除一张表

    当我们想删除一张表的全部数据时,我们可以使用 truncate 关键字,但如果要删除的表的主键被引用了,那么就无法执行语句. 1.制作清除数据的工具 ,在 nuget 控制台中输入 Install-P ...

  7. October 11th 2017 Week 41st Wednesday

    If you don't know where you are going, you might not get there. 如果你不知道自己要去哪里,你可能永远到不了那里. The reward ...

  8. saxbuilder用法

    xml为我们在网络交换数据带来很大方便,在java中可以使用saxbuilder来操作xml格式文件,下面介绍一下saxbuilder的常用方法. import org.jdom.Document; ...

  9. initialProps被React-Navigation的navigation属性覆盖解决方案

    怎么开场对我来说一个是个很纠结的问题,Emmm这应该算个好开场. 最近在做一个RN的app端调试工具,在把它嵌入原生app中的时候遇到了一个问题,RN组件里面接受不到原生传过来的initialProp ...

  10. BZOJ3533:[SDOI2014]向量集(线段树,三分,凸包)

    Description 维护一个向量集合,在线支持以下操作: "A x y (|x|,|y| < =10^8)":加入向量(x,y); " Q x y l r (| ...