Problem   UVALive - 4287 - Proving Equivalences

Time Limit: 3000 mSec

Problem Description

Input

Output

Sample Input

2 4 0 3 2 1 2 1 3

Sample Output

4

2

题解:题意就是给出一个有向图,问最少添加几条有向边能够使得整张图强连通,Tarjan缩点是比较容易想到的,之后怎么办,要用到一个结论:如果图中有a个入度为零的点,b个出度为零的点,那么max(a, b)就是答案,这个东西不太容易严格证明(在一份ppt上看到说证明难,略。。。),但是形式上想一想还是挺对的。此外mark两个结论,这两个是很容易严格证明的:

  1、DAG中唯一出度为0的点一定可以由任意点出发到达。(证明:由于无环,因此所有点都要终止在出度为0的点)

  2、DAG中所有入度不为0的点一定可以由某个入度为0的点出发到达。(证明:由于无环,入度不为零的点逆着走一定终止在入度为0的点)

  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define REP(i, n) for (int i = 1; i <= (n); i++)
  6. #define sqr(x) ((x) * (x))
  7.  
  8. const int maxn = + ;
  9. const int maxm = + ;
  10. const int maxs = + ;
  11.  
  12. typedef long long LL;
  13. typedef pair<int, int> pii;
  14. typedef pair<double, double> pdd;
  15.  
  16. const LL unit = 1LL;
  17. const int INF = 0x3f3f3f3f;
  18. const LL mod = ;
  19. const double eps = 1e-;
  20. const double inf = 1e15;
  21. const double pi = acos(-1.0);
  22.  
  23. int n, m;
  24. vector<int> G[maxn];
  25. int dfs_clock, scc_cnt;
  26. int pre[maxn], sccno[maxn];
  27. stack<int> S;
  28.  
  29. int dfs(int u)
  30. {
  31. S.push(u);
  32. int lowu = pre[u] = ++dfs_clock;
  33. for (auto v : G[u])
  34. {
  35. if (!pre[v])
  36. {
  37. int lowv = dfs(v);
  38. lowu = min(lowu, lowv);
  39. }
  40. else if (!sccno[v])
  41. {
  42. lowu = min(lowu, pre[v]);
  43. }
  44. }
  45. if (lowu == pre[u])
  46. {
  47. scc_cnt++;
  48. for (;;)
  49. {
  50. int t = S.top();
  51. S.pop();
  52. sccno[t] = scc_cnt;
  53. if (t == u)
  54. break;
  55. }
  56. }
  57. return lowu;
  58. }
  59.  
  60. void find_scc()
  61. {
  62. dfs_clock = scc_cnt = ;
  63. memset(pre, , sizeof(pre));
  64. memset(sccno, , sizeof(sccno));
  65. for (int i = ; i < n; i++)
  66. {
  67. if (!pre[i])
  68. {
  69. dfs(i);
  70. }
  71. }
  72. }
  73.  
  74. int out[maxn], in[maxn];
  75.  
  76. int main()
  77. {
  78. ios::sync_with_stdio(false);
  79. cin.tie();
  80. //freopen("input.txt", "r", stdin);
  81. //freopen("output.txt", "w", stdout);
  82. int T;
  83. cin >> T;
  84. while (T--)
  85. {
  86. memset(out, , sizeof(out));
  87. memset(in, , sizeof(in));
  88. cin >> n >> m;
  89. for (int i = ; i < n; i++)
  90. {
  91. G[i].clear();
  92. }
  93. int u, v;
  94. for (int i = ; i < m; i++)
  95. {
  96. cin >> u >> v;
  97. u--, v--;
  98. G[u].push_back(v);
  99. }
  100. find_scc();
  101. for (int u = ; u < n; u++)
  102. {
  103. for (auto v : G[u])
  104. {
  105. if (sccno[v] != sccno[u])
  106. {
  107. out[sccno[u]]++;
  108. in[sccno[v]]++;
  109. }
  110. }
  111. }
  112. int a = , b = ;
  113. for (int i = ; i <= scc_cnt; i++)
  114. {
  115. if (!out[i])
  116. a++;
  117. if (!in[i])
  118. b++;
  119. }
  120. int ans = max(a, b);
  121. if (scc_cnt == )
  122. ans = ;
  123. cout << ans << endl;
  124. }
  125. return ;
  126. }

UVALive - 4287 - Proving Equivalences(强连通分量)的更多相关文章

  1. UvaLive 4287 Proving Equivalences 强连通缩点

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

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

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

  3. UVALive Proving Equivalences (强连通分量,常规)

    题意: 给一个有向图,问添加几条边可以使其强连通. 思路: tarjan算法求强连通分量,然后缩点求各个强连通分量的出入度,答案是max(入度为0的缩点个数,出度为0的缩点个数). #include ...

  4. UVALive - 4287 Proving Equivalences

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

  5. UVALive 4287 Proving Equivalences(缩点)

    等价性问题,给出的样例为 a->b的形式,问要实现全部等价(即任意两个可以互相推出),至少要加多少个形如 a->b的条件. 容易想到用强连通缩点,把已经实现等价的子图缩掉,最后剩余DAG. ...

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

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

  7. HDU2767Proving Equivalences[强连通分量 缩点]

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

  8. hdu2767 Proving Equivalences --- 强连通

    给一个图,问至少加入�多少条有向边能够使图变成强连通的. 原图是有环的,缩点建图,在该DAG图上我们能够发现,要使该图变成强连通图必须连成环 而加入�最少的边连成环,就是把图上入度为0和出度为0的点连 ...

  9. hdu - 2667 Proving Equivalences(强连通)

    http://acm.hdu.edu.cn/showproblem.php?pid=2767 求至少添加多少条边才能变成强连通分量.统计入度为0的点和出度为0的点,取最大值即可. #include & ...

随机推荐

  1. Chapter 4 Invitations——12

    "I don't know what you mean," I said, my voice guarded. “我不知道你什么意思”我声音谨慎地说道. "It's be ...

  2. 用tensorflow学习贝叶斯个性化排序(BPR)

    在贝叶斯个性化排序(BPR)算法小结中,我们对贝叶斯个性化排序(Bayesian Personalized Ranking, 以下简称BPR)的原理做了讨论,本文我们将从实践的角度来使用BPR做一个简 ...

  3. centos中安装虚拟机

    我这里选用的虚拟机软件为virtualbox 下载wget http://download.virtualbox.org/virtualbox/5.2.2/VirtualBox-5.2-5.2.2_1 ...

  4. 修改sql数据库名称

    USE master; GO DECLARE @SQL VARCHAR(MAX); SET @SQL='' SELECT @SQL=@SQL+'; KILL '+RTRIM(SPID) FROM ma ...

  5. leetcode — reverse-linked-list

    /** * Source : https://leetcode.com/problems/reverse-linked-list/ * * * Reverse a singly linked list ...

  6. 应用AI芯片加速 Hadoop 3.0 纠删码的计算性能

    本文由云+社区发表 做为大数据生态系统中最重要的底层存储文件系统HDFS,为了保证系统的可靠性,HDFS通过多副本的冗余来防止数据的丢失.通常,HDFS中每一份数据都设置两个副本,这也使得存储利用率仅 ...

  7. SpringBoot整合系列-PageHelper分页插件

    原创作品,可以转载,但是请标注出处地址:https://www.cnblogs.com/V1haoge/p/9971043.html SpringBoot整合MyBatis分页插件PageHelper ...

  8. 第31章 日志 - Identity Server 4 中文文档(v1.0.0)

    IdentityServer使用ASP.NET Core提供的标准日志记录工具.Microsoft文档有一个很好的介绍和内置日志记录提供程序的描述. 我们大致遵循Microsoft使用日志级别的指导原 ...

  9. xxxx-xx-xx的时间的加减

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...

  10. MIUI10系统怎么样刷成开发版获得ROOT权限

    小米的设备不同手机型号正常情况下小米官方论坛都提供两个不同系统,可分为稳定版和开发版,稳定版没有提供root超级权限管理,开发版中就提供了root超级权限,在很多工作的时候我们需要使用的一些功能强大的 ...