思路:先缩点成有向无环图,则必然含有出度为0的点/入度为0的点,因为要使添加的边尽量多,最多最多也就n*(n-1)条减去原来的m条边,这样是一个强连通图,问题转化为最少去掉几条,使图不强连通,原来图中入度的点,若不添加入度,则必然不连通,同理出度为0的也一样,所以,找入度/出度为0的点中, ki(n-ki)最小的,这里KI是缩点后该SCC中的点数量,这个结果就是最小去掉的边数了。

思路清晰,1A。

  1. #include<iostream>
  2. #include<vector>
  3. #include<cstdio>
  4. #include<cstring>
  5. #include<stack>
  6. using namespace std;
  7. int n,m;
  8. const int maxv=100030;
  9. vector<vector<int> >edges(maxv);
  10. int visited[maxv]; int low[maxv]; int dfn[maxv];
  11. int ind[maxv]; int outd[maxv]; int sccnum[maxv];
  12. int scc[maxv];
  13. int num;int times;
  14. stack<int>s;
  15. int instack[maxv];
  16. void tarjan(int u)
  17. {
  18. low[u]=dfn[u]=times++;
  19. instack[u]=1;
  20. s.push(u);
  21. int len=edges[u].size();
  22. for(int i=0;i<len;i++)
  23. {
  24. int v=edges[u][i];
  25. if(visited[v]==0)
  26. {
  27. visited[v]=1;
  28. tarjan(v);
  29. if(low[u]>low[v])low[u]=low[v];
  30. }
  31. else if(instack[v]&&low[u]>dfn[v])
  32. {
  33. low[u]=dfn[v];
  34. }
  35. }
  36. if(dfn[u]==low[u]) //在一个SCC
  37. {
  38. num++;int temp;int snum=0;
  39. do
  40. {
  41. snum++;
  42. temp=s.top();
  43. instack[temp]=0;
  44. s.pop();
  45. scc[temp]=num;
  46. } while(temp!=u);
  47. sccnum[num]=snum;
  48. }
  49. }
  50. void readin() //读入数据
  51. {
  52. scanf("%d%d",&n,&m);
  53. int a,b;
  54. for(int i=1;i<=m;i++)
  55. {
  56. scanf("%d%d",&a,&b);
  57. edges[a].push_back(b);
  58. }
  59. }
  60. void initialize()
  61. {
  62. num=times=0;
  63. for(int i=0;i<=100000;i++)
  64. {
  65. dfn[i]=low[i]=ind[i]=outd[i]=visited[i]=sccnum[i]=scc[i]=0;
  66. edges[i].clear();
  67. }
  68. }
  69. int solve()
  70. {
  71. for(int i=1;i<=n;i++)
  72. if(visited[i]==0)
  73. {
  74. visited[i]=1;
  75. tarjan(i);
  76. }
  77. if(num==1){return -1;}
  78. for(int i=1;i<=n;i++)
  79. {
  80. int len=edges[i].size();
  81. for(int j=0;j<len;j++)
  82. {
  83. int v=edges[i][j];
  84. if(scc[v]!=scc[i])
  85. {
  86. outd[scc[i]]++;
  87. ind[scc[v]]++;
  88. }
  89. }
  90. }
  91. int mincut=1000000000;
  92. for(int i=1;i<=num;i++)
  93. {
  94. int temp=0;
  95. if(outd[i]==0||ind[i]==0)
  96. {
  97. temp=sccnum[i]*(n-sccnum[i]);
  98. if(temp<mincut)mincut=temp;
  99. }
  100. }
  101. return n*(n-1)-m-mincut;
  102. }
  103. int main()
  104. {
  105. int T;
  106. cin>>T;int cases=1;
  107. while(T--)
  108. {
  109. initialize();
  110. readin();
  111. int ans=solve();
  112. printf("Case %d: %d\n",cases++,ans);
  113. }
  114. return 0;
  115. }

hdu4635 有向图最多添加多少边使图仍非强连通的更多相关文章

  1. poj 3177 Redundant Paths【求最少添加多少条边可以使图变成双连通图】【缩点后求入度为1的点个数】

    Redundant Paths Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11047   Accepted: 4725 ...

  2. poj 3352 Road Construction【边双连通求最少加多少条边使图双连通&&缩点】

    Road Construction Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10141   Accepted: 503 ...

  3. Strongly connected HDU - 4635 原图中在保证它不是强连通图最多添加几条边

    1 //题意: 2 //给你一个有向图,如果这个图是一个强连通图那就直接输出-1 3 //否则,你就要找出来你最多能添加多少条边,在保证添加边之后的图依然不是一个强连通图的前提下 4 //然后输出你最 ...

  4. Android -- FragmentActivity添加Fragment的序列图

    FragmentActivity添加Fragment的序列图

  5. Android 如何添加一个apk使模拟器和真机都编译进去 m

    添加一个apk都需要将LOCAL_PACKAGE_NAME的值添加到PRODUCT_PACKAGES才行.而PRODUCT_PACKAGES一般在build/target/product/目录下的文件 ...

  6. HDU 4635 —— Strongly connected——————【 强连通、最多加多少边仍不强连通】

    Strongly connected Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u ...

  7. LoadRunner添加Weblogic监控的注意事项(非单纯的操作步骤)

    LoadRunner添加Weblogic监控的注意事项(非单纯的操作步骤)   关于LR如何监控Weblogic(JMX方式)的操作就不在这里多说了,帮助文件和网上的介绍已经非常多了,关键是对各操作步 ...

  8. hdu4635(最多加多少边,使得有向图不是强连通图)

    连边的最后肯定是两个集合x,yx集合的每个元素,到y集合中的每个元素都是单向的边x集合,和y集合都是完全图设a为x集合的点的个数, b为y集合的那么答案就是 a * b + a*(a-1) + b*( ...

  9. POJ 1236--Network of Schools【scc缩点构图 &amp;&amp; 求scc入度为0的个数 &amp;&amp; 求最少加几条边使图变成强联通】

    Network of Schools Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 13325   Accepted: 53 ...

随机推荐

  1. python列表之append与extend方法比较

    append和extend是列表的两种添加元素方式,但这两种方式却又有些不同之处.那么不同之处在哪里呢,我们通过对二者的定义和实例来看一看. list.append() 1.定义:L.append(o ...

  2. Vue之数据传递

    基础:vue的响应式规则 简单的props更新 父组件 <template> <div> <block-a :out-data="x">< ...

  3. Applied Nonparametric Statistics-lec10

    Ref:https://onlinecourses.science.psu.edu/stat464/print/book/export/html/14 估计CDF The Empirical CDF ...

  4. printk的使用技巧

    在 linux/kernel.h 中有相应的宏对应. #define KERN_EMERG    "<0>"    /* system is unusable */#d ...

  5. i2c drivers

    Linux设备驱动程序架构分析之一个I2C驱动实例   转载于:http://blog.csdn.net/liuhaoyutz 内核版本:3.10.1   编写一个I2C设备驱动程序的工作可分为两部分 ...

  6. Linux学习-什么是例行性工作排程

    那么 Linux 的例行性工作是如何进行排程的呢?所谓的排程就是将这些工作安排执行的流程之意! 咱们的 Linux 排程就是透过 crontab 与 at 这两个东西! Linux 工作排程的种类: ...

  7. ASP.Net教程系列:多线程编程实战(一)

    Web开发中使用多线程可以增强用户体验,尤其是多用户.多任务.海量数据和资源紧张的情况下.所以我们的ASP.Net教程设立多线程编程实战专题.下面这些代码范例都是入门级的,希望对对大家学习ASP.Ne ...

  8. js时间格式化工具,时间戳格式化,字符串转时间戳

    在开发中经常会用到时间格式化,有时候在网上搜索一大堆但不是自己想要的,自己总结一下,写一个时间格式化工具方便以后直接使用,欢迎大家来吐槽…… 1 2 3 4 5 6 7 8 9 10 11 12 13 ...

  9. ubuntu14.04 不能关机,一直停在关机界面

    1.emotion: 最近在使用Ubuntu14.04 LTS时,输入shutdown -h now之后,Ubuntu就一直停在关机界面,始终不能shutdown,不得不手动按下电源button.忍受 ...

  10. iOS学习笔记29-系统服务(二)通讯录

    一.通讯录 iOS中的通讯录是存储在数据库中的,由于iOS的权限设计,开发人员是不允许直接访问通讯录数据库的,实现通讯录操作需要使用到AddressBook.framework框架. AddressB ...