给一个图,问至少加入�多少条有向边能够使图变成强连通的。

原图是有环的,缩点建图,在该DAG图上我们能够发现,要使该图变成强连通图必须连成环

而加入�最少的边连成环,就是把图上入度为0和出度为0的点连上,那么其它的点就都能够互相到达了

所以答案就是max(入度为0的点,出度为0的点)

  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4. #include <cstdio>
  5. #include <cmath>
  6. #include <algorithm>
  7. #include <vector>
  8. #include <queue>
  9. #include <map>
  10. #define inf 0x3f3f3f3f
  11. #define eps 1e-6
  12. #define ll __int64
  13. #define M 20010//图中点数
  14. using namespace std;
  15.  
  16. int sta[M],top; //Tarjan 算法中的栈
  17. bool vis[M]; //检查是否在栈中
  18. int dfn[M]; //深度优先搜索訪问次序
  19. int low[M]; //能追溯到的最早的次序
  20. int ccnt; //有向图强连通分量个数
  21. int id; //索引號
  22. vector<int> e[M]; //邻接表表示
  23. vector<int> part[M]; //获得强连通分量结果
  24. int inpart[M]; //记录每一个点在第几号强连通分量里
  25. int degree[M]; //记录每一个强连通分量的度
  26. vector<int> edge[M];//缩点后建图
  27. int ans,n,m,dp[M],in[M],point[M],out[M];
  28.  
  29. void tarjan(int x)
  30. {
  31. int i,j;
  32. dfn[x]=low[x]=id++;
  33. vis[x]=1;
  34. sta[++top]=x;
  35. for(i=0;i<e[x].size();i++)
  36. {
  37. j=e[x][i];
  38. if(dfn[j]==-1)
  39. {
  40. tarjan(j);
  41. low[x]=min(low[x],low[j]);
  42. }
  43. else if(vis[j])
  44. low[x]=min(low[x],dfn[j]);
  45. }
  46. if(dfn[x]==low[x])
  47. {
  48. do
  49. {
  50. j=sta[top--];
  51. vis[j]=0;
  52. part[ccnt].push_back(j);
  53. inpart[j]=ccnt;
  54. point[ccnt]++;
  55. }while(j!=x);
  56. ccnt++;
  57. }
  58. }
  59.  
  60. void solve(int n)
  61. {
  62. memset(sta,-1,sizeof sta);
  63. memset(vis,0,sizeof vis);
  64. memset(dfn,-1,sizeof dfn);
  65. memset(low,-1,sizeof low);
  66. memset(point,0,sizeof point);
  67.  
  68. top=ccnt=id=0;
  69. for(int i=1;i<=n;i++)
  70. if(dfn[i]==-1)
  71. tarjan(i);
  72. }
  73.  
  74. int dfs(int x)
  75. {
  76. if(dp[x]) return dp[x];
  77. dp[x]=point[x];
  78. int i;
  79. for(i=0;i<edge[x].size();i++)
  80. {
  81. int tmp=edge[x][i];
  82. dp[x]=max(dp[x],point[x]+dfs(tmp));
  83. }
  84. return dp[x];
  85. }
  86.  
  87. int main()
  88. {
  89. int n,m,i,j,a,b,t;
  90. scanf("%d",&t);
  91. while(t--)
  92. {
  93. scanf("%d%d",&n,&m);
  94. for(i=0;i<=n;i++)
  95. {
  96. part[i].clear();
  97. e[i].clear();
  98. edge[i].clear();
  99. }
  100. while(m--)
  101. {
  102. scanf("%d%d",&a,&b);
  103. e[a].push_back(b);
  104. }
  105. solve(n);
  106. memset(in,0,sizeof in);
  107. memset(out,0,sizeof out);
  108. for(i=1;i<=n;i++)//枚举原图中的边
  109. {
  110. for(j=0;j<e[i].size();j++)
  111. {
  112. a=inpart[i];
  113. b=inpart[e[i][j]];//
  114. if(a!=b)
  115. {
  116. in[b]++;
  117. out[a]++;
  118. edge[a].push_back(b);
  119. }
  120. }
  121. }
  122.  
  123. a=b=0;
  124. for(i=0;i<ccnt;i++)//
  125. {
  126. if(in[i]==0)
  127. a++;
  128. if(out[i]==0)
  129. b++;
  130. }
  131. if(ccnt==1) printf("0\n");
  132. else printf("%d\n",max(a,b));
  133. }
  134. return 0;
  135. }

hdu2767 Proving Equivalences --- 强连通的更多相关文章

  1. HDU2767 Proving Equivalences(加边变为强联通图)

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

  2. hdu2767 Proving Equivalences Tarjan缩点

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

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

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

  4. hdu 2767 Proving Equivalences 强连通缩点

    给出n个命题,m个推导,问最少添加多少条推导,能够使全部命题都能等价(两两都能互推) 既给出有向图,最少加多少边,使得原图变成强连通. 首先强连通缩点,对于新图,每一个点都至少要有一条出去的边和一条进 ...

  5. HDU2767 Proving Equivalences

    Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission( ...

  6. HDU 2767:Proving Equivalences(强连通)

    题意: 一个有向图,问最少加几条边,能让它强连通 方法: 1:tarjan 缩点 2:采用如下构造法: 缩点后的图找到所有头结点和尾结点,那么,可以这么构造:把所有的尾结点连一条边到头结点,就必然可以 ...

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

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

  8. HDU 2767 Proving Equivalences(强连通 Tarjan+缩点)

    Consider the following exercise, found in a generic linear algebra textbook. Let A be an n × n matri ...

  9. UvaLive 4287 Proving Equivalences 强连通缩点

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

随机推荐

  1. Ftp实现文件同步

    通常在做服务器与服务器文件.服务器与本地文件同步时通过Ftp服务实现,下面就以服务器文件和本地同步为例,介绍一下Ftp同步文件:首先建立一个Ftp站点服务,基本身份验证登陆,端口号为默认的21:Ftp ...

  2. Java基础知识强化55:经典排序之归并排序(MergeSort)

    1. 归并排序的原理: 原理,把原始数组分成若干子数组,对每一个子数组进行排序, 继续把子数组与子数组合并,合并后仍然有序,直到全部合并完,形成有序的数组 举例: 无序数组[6 2 4 1 5 9] ...

  3. How to get multi-touch working(Linux and Andriod)

    1.在hid-ids.h中加入vid pid           2.在hid-multitouch..c->mt_devices[] 中加入          {                ...

  4. AnkhSVN 中文版 支持VS2015

    简介:AnkhSVN是一款在VS中管理Subversion的插件,您可以在VS中轻松的提交.更新.添加文件,而不用在命令行或资源管理器中提交,而且该插件属于开源项目. 这个版本是简体中文的重新编译版本 ...

  5. datagrid数据导出到excel文件给客户端下载的几种方法

    方法一:导出到csv文件,存放在服务器端任一路径,然后给客户下载 优点: 1.可以进行身份认证后给客户下载,如果放到非web目录就没有对应的url,客户无法随时下载. 2.也是因为生成了文件,所以占用 ...

  6. css float父元素高度塌陷

    css float父元素高度塌陷 float 使父元素高度塌陷不是BUG,反而是标准. float 原本是为了解决文字环绕才出现的. 当然有的时候要解决高度塌陷的问题 以下几个方法可以解决float ...

  7. DOM中的NodeList与HTMLCollection

    最近在看<Javascript高级程序设计>的时候,看到了这样一句话:“理解NodeList和HTMLCollection,是从整体上透彻理解DOM的关键所在.”,所以觉得应该写一篇关于N ...

  8. OC基础 代理和协议

    OC基础 代理和协议 1.协议 (1)oc语言中得协议:一组方法列表,不需要我们自己实现,由遵守协议的类来实现协议所定制的方法. (2)协议的使用步骤:制定协议-->遵守协议-->实现协议 ...

  9. dom的element类型

    1)getElementById 后面的nodeName和tagName都一样 var a=document.getElementById("my_div"); console.l ...

  10. Word隐藏回车符技巧

    每一次在Word中敲击回车时,都会留下一个回车符,回车次数多了回车符也就跟着变多了,这的确是太影响视觉效果了,我们要如何操作才能将这些回车符去掉呢?特意为大家献上Word2003和Word2007中隐 ...