等价性问题,给出的样例为 a->b的形式,问要实现全部等价(即任意两个可以互相推出),至少要加多少个形如 a->b的条件。

容易想到用强连通缩点,把已经实现等价的子图缩掉,最后剩余DAG。要推出一个方案,YY后取“出度为零”和“入度为零”的点数的较大值。

理由:假定出度为零的点数较多,即是我们通常意义上的树的形式(当然,DAG是图,这里只是类比)。

根可以推出其所有子孙,事实上任意一个点都可以推出其子孙,那么只要让该节点推出树根,就可以推出整棵树上所有的节点了。那么多棵树为什么不是相乘呢?,借题目中的范例,a->b,b->c,c->a,形成一个循环即可。

本质:给定一个有向图,问是否加上多少条边,使原图构成强连通。

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stack>
  4. #include<algorithm>
  5. using namespace std;
  6.  
  7. const int MAXN=;
  8.  
  9. struct Edge{
  10. int v,next;
  11. Edge(){}
  12. Edge(int _v,int _next):v(_v),next(_next){}
  13. }edge[MAXN];
  14.  
  15. int tol,head[MAXN];
  16. int low[MAXN],dfn[MAXN],sccno[MAXN],scc_cnt,TT;
  17.  
  18. stack<int >stk;
  19.  
  20. void init()
  21. {
  22. tol=;
  23. memset(head,-,sizeof(head));
  24. }
  25.  
  26. void add(int u,int v)
  27. {
  28. edge[tol]=Edge(v,head[u]);
  29. head[u]=tol++;
  30. }
  31.  
  32. void dfs(int u)
  33. {
  34. int v;
  35. dfn[u]=low[u]=++TT;
  36. stk.push(u);
  37. for(int i=head[u];i!=-;i=edge[i].next)
  38. {
  39. v=edge[i].v;
  40. if(!dfn[v]){
  41. dfs(v);
  42. low[u]=min(low[u],low[v]);
  43. }else if(!sccno[v]){
  44. low[u]=min(low[u],dfn[v]);
  45. }
  46. }
  47. if(low[u]==dfn[u]){
  48. scc_cnt++;
  49. do{
  50. v=stk.top();
  51. stk.pop();
  52. sccno[v]=scc_cnt;
  53. }while(v!=u);
  54. }
  55. }
  56.  
  57. void tarjan(int n)
  58. {
  59. scc_cnt=TT=;
  60. memset(low,,sizeof(low));
  61. memset(dfn,,sizeof(dfn));
  62. memset(sccno,,sizeof(sccno));
  63.  
  64. while(!stk.empty())
  65. stk.pop();
  66. for(int i=;i<=n;i++)
  67. if(!dfn[i])
  68. dfs(i);
  69. }
  70.  
  71. int main()
  72. {
  73. int T,n,m;
  74. int a[MAXN],b[MAXN];
  75. scanf("%d",&T);
  76. while(T--)
  77. {
  78. scanf("%d%d",&n,&m);
  79.  
  80. init();
  81. for(int i=;i<m;i++)
  82. {
  83. scanf("%d%d",&a[i],&b[i]);
  84. add(a[i],b[i]);
  85. }
  86.  
  87. tarjan(n);
  88.  
  89. int in[MAXN],out[MAXN];
  90. memset(in,,sizeof(in));
  91. memset(out,,sizeof(out));
  92. for(int i=;i<m;i++)
  93. {
  94. if(sccno[a[i]]!=sccno[b[i]]){
  95. in[sccno[b[i]]]++;
  96. out[sccno[a[i]]]++;
  97. }
  98. }
  99.  
  100. int innum,outnum;
  101. innum=outnum=;
  102. for(int i=;i<=scc_cnt;i++)
  103. {
  104. if(!in[i])
  105. innum++;
  106. if(!out[i])
  107. outnum++;
  108. }
  109.  
  110. if(scc_cnt==)printf("0\n");
  111. else printf("%d\n",max(innum,outnum));
  112. }
  113. return ;
  114. }

UVALive 4287 Proving Equivalences(缩点)的更多相关文章

  1. UVALive - 4287 - Proving Equivalences(强连通分量)

    Problem   UVALive - 4287 - Proving Equivalences Time Limit: 3000 mSec Problem Description Input Outp ...

  2. UvaLive 4287 Proving Equivalences 强连通缩点

    原题链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  3. UVALIVE 4287 Proving Equivalences (强连通分量+缩点)

    题意:给定一个图,问至少加入多少条边能够使这个图强连通. 思路:首先求出这个图的强连通分量.然后把每个强连通分量缩成一个点.那么这个图变成了一个DAG,求出全部点的入度和出度,由于强连通图中每个节点的 ...

  4. UVALive - 4287 Proving Equivalences

    给定n个命题之间的已经证明的关系如 a b表示已经证明蕴含式a→b,要求还需要再作多少次证明使得所有的命题都是等价的.将每个命题看成一个点,已经证明的命题之间连一条边,问题转化为添加多少条单向边使得图 ...

  5. Proving Equivalences(缩点+有环图变强连通分量)【tarjian算法】

    Proving Equivalences 题目链接(点击) 参考博客(点击) Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768 ...

  6. UVALive 4287 Proving Equivalence (强连通分量)

    把证明的关系看出一张图,最终就是要所有的点都在至少一个环中.环的判断和度数有关. 用tarjan找强连通分量,在一个强连通分量点已经等价缩点以后形成一个DAG,计算入度为0的点数a, 出度为0的b,取 ...

  7. 训练指南 UVALive - 4287 (强连通分量+缩点)

    layout: post title: 训练指南 UVALive - 4287 (强连通分量+缩点) author: "luowentaoaa" catalog: true mat ...

  8. Proving Equivalences (hdu 2767 强联通缩点)

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  9. hdoj 2767 Proving Equivalences【求scc&&缩点】【求最少添加多少条边使这个图成为一个scc】

    Proving Equivalences Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

随机推荐

  1. nenu contest3 The 5th Zhejiang Provincial Collegiate Programming Contest

    ZOJ Problem Set - 2965 Accurately Say "CocaCola"!  http://acm.zju.edu.cn/onlinejudge/showP ...

  2. HTTP 错误 403.14 - Forbidden

    在打开一个网站时,显示HTTP 错误 403.14 - Forbidden 是一件很不幸的事情.我这几天打开某网站就出现了这个问题.Web 服务器被配置为不列出此目录的内容,错误代码0x0000000 ...

  3. GameMap其他初始化

    //其他初始化 init_prop();//初始化道具 init_ornamemtal();//初始化装饰物 init_monster_type_info();//初始化怪物基本信息 这个比较重要在加 ...

  4. iOS开发之深入探讨runtime机制02-runtime的简单使用

    runtime机制为我们提供了一系列的方法让我们可以在程序运行时动态修改类.对象中的所有属性.方法. 下面就介绍运行时一种很常见的使用方式,字典转模型.当然,你可能会说,“我用KVO直接 setVal ...

  5. shallow copy & deep copy

    1.深复制与浅复制的概念 ->浅复制(shallow copy)概念   在SDK Guides中(搜索copy),官方给出的浅复制概念为: Copying compound objects, ...

  6. uva 11825

    刘书上例题  关于集合的动态规划 #include <cstdio> #include <cstdlib> #include <cmath> #include &l ...

  7. ural 1864

    题意描述不清   而且还卡精度 ~~ #include <cstdio> #include <cstring> #include <iostream> using ...

  8. Unity3D研究院之IOS全自动打包生成ipa

    接着上一篇文章, 自动生成framework,这篇文章我把shell自动化打包ipa整理了一下,希望大家喜欢,嘿嘿.. 建议大家先看一下上一篇文章.http://www.xuanyusong.com/ ...

  9. 词法分析器flex的使用

    词法分析器flex的功能说起来就是一句话,将正则表达式转化为c代码. flex编译成功后会生成一个flex.exe的可执行文件.此时,我们需要一个定义了正则表达式 动作的input文件.例如test. ...

  10. C#扩展方法入门

    扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的. 它们的第一个参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀. 仅当你使用 using 指令将命名空间显式导入到源代码 ...