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

先求出所有的强连通分量,然后缩点构成一个SCC图,统计其中入度为0的点个数a,以及出度为0的点的个数b,max(a,b)就是需要再作的证明.注意当图一开始就是强连通时,不需要作出证明了.

来自刘汝佳算法训练指南代码:

  1. #include <iostream>
  2. #include <sstream>
  3. #include <cstdio>
  4. #include <climits>
  5. #include <cstring>
  6. #include <cstdlib>
  7. #include <string>
  8. #include <stack>
  9. #include <map>
  10. #include <cmath>
  11. #include <vector>
  12. #include <queue>
  13. #include <algorithm>
  14. #define esp 1e-6
  15. #define pi acos(-1.0)
  16. #define pb push_back
  17. #define mp(a, b) make_pair((a), (b))
  18. #define in freopen("in.txt", "r", stdin);
  19. #define out freopen("out.txt", "w", stdout);
  20. #define print(a) printf("%d\n",(a));
  21. #define bug puts("********))))))");
  22. #define stop system("pause");
  23. #define Rep(i, c) for(__typeof(c.end()) i = c.begin(); i != c.end(); i++)
  24. #define pragma comment(linker, "/STACK:102400000, 102400000")
  25. #define inf 0x0f0f0f0f
  26.  
  27. using namespace std;
  28. typedef long long LL;
  29. typedef vector<int> VI;
  30. typedef pair<int, int> pii;
  31. typedef vector<pii,int> VII;
  32. typedef vector<int>:: iterator IT;
  33. const int maxn = 22222;
  34. int pre[maxn], lowlink[maxn], sccno[maxn], dfs_clock, scc_cnt;
  35. int in0[maxn], out0[maxn];
  36. VI g[maxn];
  37. stack<int> S;
  38. void dfs(int u)
  39. {
  40. S.push(u);
  41. lowlink[u] = pre[u] = ++dfs_clock;
  42. for(int i = 0; i < g[u].size(); i++)
  43. {
  44. int v = g[u][i];
  45. if(!pre[v])
  46. {
  47. dfs(v);
  48. lowlink[u] = min(lowlink[u], lowlink[v]);
  49. }
  50. else if(!sccno[v])
  51. {
  52. lowlink[u] = min(lowlink[u], pre[v]);
  53. }
  54. }
  55. if(lowlink[u] == pre[u])
  56. {
  57. scc_cnt++;
  58. for(;;)
  59. {
  60. int x = S.top();
  61. S.pop();
  62. sccno[x] = scc_cnt;
  63. if(x == u) break;
  64. }
  65. }
  66. }
  67. void find_scc(int n)
  68. {
  69. memset(pre, 0, sizeof(pre));
  70. memset(sccno, 0, sizeof(sccno));
  71. dfs_clock = scc_cnt = 0;
  72. for(int i = 0; i < n; i++)
  73. if(!pre[i]) dfs(i);
  74. }
  75. int main(void)
  76. {in
  77. int n, m;
  78. int T;
  79. for(int t = scanf("%d", &T); t <= T; t++)
  80. {
  81. for(int i = 0; i < maxn; i++)
  82. g[i].clear();
  83. memset(in0, 1, sizeof(in0));
  84. memset(out0, 1, sizeof(out0));
  85. scanf("%d%d", &n, &m);
  86. while(m--)
  87. {
  88. int u, v;
  89. scanf("%d%d", &u, &v);
  90. u--, v--;
  91. g[u].pb(v);
  92. }
  93. find_scc(n);
  94. for(int u = 0; u < n; u++)
  95. for(int i = 0; i < g[u].size(); i++)
  96. {
  97. int v = g[u][i];
  98. if(sccno[v] != sccno[u])
  99. in0[sccno[v]] = out0[sccno[u]] = 0;
  100. }
  101. int a = 0, b= 0;
  102. for(int i = 1; i <= scc_cnt; i++)
  103. {
  104. if(in0[i]) a++;
  105. if(out0[i]) b++;
  106. }
  107. int ans = 0;
  108. if(scc_cnt != 1) ans = max(a, b);
  109. printf("%d\n",ans);
  110. }
  111. return 0;
  112. }

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(缩点)

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

  3. UvaLive 4287 Proving Equivalences 强连通缩点

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

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

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

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

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

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

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

  7. hdu 2767 Proving Equivalences

    Proving Equivalences 题意:输入一个有向图(强连通图就是定义在有向图上的),有n(1 ≤ n ≤ 20000)个节点和m(0 ≤ m ≤ 50000)条有向边:问添加几条边可使图变 ...

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

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

  9. Proving Equivalences(加多少边使其强联通)

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

随机推荐

  1. php入门实现留言板

    首先由一个文本文档read.txt liulan.html <!doctype html> <html lang="en"> <head> &l ...

  2. 《Pro Git》学习笔记

    1.Git远程模型示意图 Remote:远程仓库 Repository:本地仓库 Index:暂存区 workspace:当前工作区 2.取得Git仓库 2.1 初始化新仓库     git init ...

  3. Vimtutor练习心得

    A. 光标定位(482) ctr + g          显示光标当前所在的行数 shift + g(G)    光标移动到文档末尾 gg                移动到文档首行 数字 + G ...

  4. apache ambari web页面无法访问解决办法

    ambari-server启动成功,但是页面无法访问 作者:Bo liang链接:http://www.zhihu.com/question/34405898/answer/115001510来源:知 ...

  5. dorado抽取js

    dorado创建的视图文件如果有控件拥有事件的话,那么它是可以抽取js的, 右键视图->抽取JavaScript 然后就会出现一个同名的.js文件 (注意,所有的属性需要有id,因为js需要绑定 ...

  6. [leetcode]最长递增序列

    class Solution { public: int lengthOfLIS(vector<int>& nums) { int n=nums.size(); ) ; vecto ...

  7. Poj 2159 / OpenJudge 2159 Ancient Cipher

    1.链接地址: http://poj.org/problem?id=2159 http://bailian.openjudge.cn/practice/2159 2.题目: Ancient Ciphe ...

  8. crontab环境变量问题

    今天设置linux定时任务时,python内调用的shell指令总执行失败,单独调用python脚本则无问题,考虑到是环境变量未生效引起. 故在执行crontab -e编辑配置文件时,将shell内执 ...

  9. centos 6.4 samba 权限 selinux权限配置

    http://www.cnblogs.com/xiaoluo501395377/archive/2013/05/26/3100444.html(参考) SELINUX 策略 配置好samba后, 输入 ...

  10. leetcode problem 33 -- Search in Rotated Sorted Array

    Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...