题目

/******************************************************************/

以下题解来自互联网:Juny的博客

思路核心:给你的闭包其实就是一个有向图;
方法:

1,对此图进行缩点,对于点数为n(n>1)的强连通分量最少要 n 条边,

对点数为 1 的强连通不需要边,这样计算出边数 m1 ;
2,在缩点后的有向无环图中进行反floyd,如果有边a->b,b->c,a->c那么显然a->c可以去掉,

就这样一直去除这样的边,直到不能再去为止,算出最终边数 m2;
3,m1+m2 即为答案;

这样做速度比较慢,但小草还没想出其他好的办法,希望有大牛指点……

/*****************************************************************/

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <cstdlib>
  5. using namespace std;
  6.  
  7. #define MAXN 20010
  8. #define MAXM 50010
  9.  
  10. struct Edge
  11. {
  12. int v, next;
  13. }edge[MAXM]; //边结点数组
  14.  
  15. int first[MAXN], stack[MAXN], DFN[MAXN], Low[MAXN], Belong[MAXM];
  16. // first[]头结点数组,stack[]为栈,DFN[]为深搜次序数组,
  17. //Belong[]为每个结点所对应的强连通分量标号数组
  18. // Low[u]为u结点或者u的子树结点所能追溯到的最早栈中结点的次序号
  19. int instack[MAXM],num[MAXN]; // instack[]为是否在栈中的标记数组
  20. int n, m, cnt, scnt, top, tot;
  21.  
  22. void init()
  23. {
  24. cnt = ;
  25. scnt = top = tot = ;
  26. memset(first, -, sizeof(first));
  27. memset(DFN, , sizeof(DFN));
  28. memset(num,,sizeof(num));
  29. }
  30.  
  31. void read_graph(int u, int v)
  32. {
  33. edge[tot].v = v;
  34. edge[tot].next = first[u];
  35. first[u] = tot++;
  36. }
  37.  
  38. void Tarjan(int v)
  39. {
  40. int t;
  41. DFN[v] = Low[v] = ++cnt;
  42. instack[v] = ;
  43. stack[top++] = v;
  44. for(int e = first[v]; e != -; e = edge[e].next)
  45. {
  46. int j = edge[e].v;
  47. if(!DFN[j])
  48. {
  49. Tarjan(j);
  50. if(Low[v] > Low[j]) Low[v] = Low[j];
  51.  
  52. }
  53. else if(instack[j] && DFN[j] < Low[v])
  54. {
  55. Low[v] = DFN[j];
  56. }
  57. }
  58. if(DFN[v] == Low[v])
  59. {
  60. scnt++;
  61. do
  62. {
  63. t = stack[--top];
  64. instack[t] = ;
  65. Belong[t] = scnt; //为缩点做准备的
  66. num[scnt]++;
  67. }while(t != v);
  68. }
  69. }
  70.  
  71. void solve()
  72. {
  73. for(int i = ; i <= n; i++)
  74. if(!DFN[i])
  75. Tarjan(i);
  76. }
  77.  
  78. int main()
  79. {
  80. int i,j,map[][],sum1,ans,map1[][];//map1[][]是缩点后新建的图
  81. while(scanf("%d",&n)!=EOF)
  82. {
  83. init();
  84. ans=;
  85. memset(map,,sizeof(map));
  86. memset(map1,,sizeof(map1));
  87. for(i=;i<=n;i++)
  88. {
  89. for(j=;j<=n;j++)
  90. {
  91. scanf("%d",&map[i][j]);
  92. if(map[i][j]==&&i!=j)
  93. {
  94. read_graph(i,j);
  95. }
  96. }
  97. }
  98. solve();
  99. sum1=;
  100. for(i=;i<=scnt;i++)
  101. {
  102. if(num[i]>)
  103. sum1+=num[i];
  104. }
  105. for(int ii=;ii<=n;ii++)
  106. {
  107. for(int jj=;jj<=n;jj++)
  108. {
  109. if(map[ii][jj]&&Belong[ii]!=Belong[jj])
  110. map1[Belong[ii]][Belong[jj]]=;
  111. }
  112. }
  113. for(int ii=;ii<=scnt;ii++)
  114. for(int jj=;jj<=scnt;jj++)
  115. for(int kk=;kk<=scnt;kk++)
  116. if(map1[ii][jj]&&map1[ii][kk]&&map1[kk][jj])//此处在缩点新建图
  117. map1[ii][jj]=;
  118. for(int ii=;ii<=scnt;ii++)
  119. for(int jj=;jj<=scnt;jj++)
  120. if(map1[ii][jj])
  121. ans++;
  122. printf("%d\n",sum1+ans);
  123. }
  124. return ;
  125. }

zoj 3232 It's not Floyd Algorithm(强联通分量,缩点)的更多相关文章

  1. 【最小割】【Dinic】【强联通分量缩点】bzoj1797 [Ahoi2009]Mincut 最小割

    结论: 满足条件一:当一条边的起点和终点不在 残量网络的 一个强联通分量中.且满流. 满足条件二:当一条边的起点和终点分别在 S 和 T 的强联通分量中.且满流.. 网上题解很多的. #include ...

  2. 【强联通分量缩点】【最长路】【spfa】CH Round #59 - OrzCC杯NOIP模拟赛day1 队爷的讲学计划

    10分算法:对于城市网络为一条单向链的数据, 20分算法:对于n<=20的数据,暴力搜出所有的可能路径. 结合以上可以得到30分. 60分算法:分析题意可得使者会带着去的城市也就是这个城市所在强 ...

  3. Tarjan求强联通分量+缩点

    提到Tarjan算法就不得不提一提Tarjan这位老人家 Robert Tarjan,计算机科学家,以LCA.强连通分量等算法闻名.他拥有丰富的商业工作经验,1985年开始任教于普林斯顿大学.Tarj ...

  4. 【强联通分量缩点】【Tarjan】bzoj1051 [HAOI2006]受欢迎的牛

    就是看是否有一些点,从其他任何点出发都可到达 定理:有向无环图中唯一出度为0的点,一定可以由任何点出发均可达. 所以缩点,若出度为零的点(强联通分量)唯一,则答案为该强联通分量中点的度数. 若不唯一, ...

  5. TOJ 3365 ZOJ 3232 It's not Floyd Algorithm / 强连通分量

    It's not Floyd Algorithm 时间限制(普通/Java):1000MS/3000MS     运行内存限制:65536KByte   描述 When a directed grap ...

  6. ZOJ 3232 It's not Floyd Algorithm --强连通分量+Floyd

    题意:给你一个传递闭包的矩阵,mp[u][v] = 1表示u可以到达v,为0代表不可到达,问你至少需要多少条边组成的传递闭包符合这个矩阵给出的关系 分析:考虑一个强连通分量,如果这个分量有n个节点,那 ...

  7. 【强联通分量缩点】【最短路】【spfa】bzoj1179 [Apio2009]Atm

    缩点后转化成 DAG图上的单源最长路问题.spfa/dp随便. #include<cstdio> #include<queue> #include<algorithm&g ...

  8. 【强联通分量缩点】【搜索】bzoj2208 [Jsoi2010]连通数

    两次dfs缩点,然后n次dfs暴搜. #include<cstdio> #include<vector> #include<cstring> using names ...

  9. BZOJ 1051 & 强联通分量

    题意: 怎么说呢...这种题目有点概括不来....还是到原题面上看好了... SOL: 求出强联通分量然后根据分量重构图,如果只有一个点没有出边那么就输出这个点中点的数目. 对就是这样. 哦还有论边双 ...

随机推荐

  1. HDU 5024 Wang Xifeng's Little Plot(枚举)

    题意:求一个图中只有一个90°拐点的路的最大长度. 分析:枚举每一个为'.'的点,求出以该点为拐点的八种路中的最大长度,再比较所有点,得出最大长度即可. 如上样例,这样是个90°的角... 注意:最多 ...

  2. [windows phone开发]新生助手的开发过程与体会三

    由于网络原因,新生助手开发介绍的博客近期一直没有更新,请大家见谅.今天向大家介绍一下新生助手中动态磁帖的实现. 在PhoneApplicationPage中添加如下引用 xmlns:toolkit=& ...

  3. 搭建eclipse环境下 Nutch+Mysql 二次开发环境

    最近看了下Nutch,目前Nutch最新版本2.3.1,支持Hbase.MongoDB等存储,但在搭建和测试过程中发现对Mysql 的支持好像有点问题. 后来将Nutch版本改为2.2.1.基于Nut ...

  4. 解析php时间戳与日期的转换

    php中时间戳与日期的转换. 实现功能:获取某个日期的时间戳,或获取某个时间的PHP时间戳. strtotime能将任何英文文本的日期时间描述解析为Unix时间戳,我们结合mktime()或date( ...

  5. nginx配置:支持phpfastcgi,nginx和php-cgi通信,部分nginx常量解释

    支持phpfastcgi的配置如下: server { listen       8000; server_name  localhost; root F:/home/projects/test; i ...

  6. Demo学习: Basic jQuery

    UniGUI是一套基于ExtJS的Delphi的WEB框架,它是使用ExtPascal来转化到ExtJS,ExtJS是一个跨浏览器的JavaScript库,因此UniGUI发布出来的程序可以在各种浏览 ...

  7. 【转】 申请对齐某种结构体大小的buffer

    在大多数情况下,编译器和C库透明地帮你处理对齐问题.POSIX 标明了通过malloc( ), calloc( ), 和 realloc( ) 返回的地址对于任何的C类型来说都是对齐的.在Linux中 ...

  8. java之classpath到底是什么

    如果你输入一个命令,比如java那么系统是如何找到这个命令的呢?按照顺序,系统先在当前目录搜索是否有java.exe, java.bat 等. 如果没有,就得到系统的PATH(不区分大小写)里面查找. ...

  9. SQLserver中的xp_cmdshell

    shell是用户与操作系统对话的一个接口,通过shell告诉操作系统让系统执行我们的指令 xp_cmdshell在sqlserver中默认是关闭的存在安全隐患. --打开xp_cmdshell ;;R ...

  10. 在Linux下写一个简单的驱动程序

    本文首先描述了一个可以实际测试运行的驱动实例,然后由此去讨论Linux下驱动模板的要素,以及Linux上应用程序到驱动的执行过程.相信这样由浅入深.由具体实例到抽象理论的描述更容易初学者入手Linux ...