做了非常久......

题目链接:  http://acm.hdu.edu.cn/showproblem.php?pid=4587

先枚举删除的第一个点,第二个点就是找割点。没有割点当然也有答案

学到的:

1、图论硬套模板不太现实,比方这道题,我能想到孤立点是特殊情况,删除孤立点。连通分支个数会降低一,可是一直处理不好,最后按缩点的做法搞了。

推断是不是孤立点的方法:

就是先用一个数组scnt[i]=j,vv[j]++  表示点i在以j为祖先的联通分支里,并且每次都让vv[j]++,就使得vv[j]表示以j为祖先的连通分支的点的个数为vv[j],这个但是没模版的。自己乱改搞出来的,開始试了几种其它方法都WA。。。

2、我自己的求割点的模板里,subset[i]==0的时候,就表示删除该点的时候。其连通分支数没有添加,这包括了悬挂顶点和孤立顶点。求是不是割点的时候。仅仅要subset[v]>0,那么v就是割点,可是在求删除该点之后的连通分支个数的时候,悬挂顶点和孤立顶点这两种情况是要分开的,假设subset[i]==0
&& i是悬挂顶点。连通分支数目不变。假设subset[i]==0 && i是孤立点。连通分支数目减一。所以1中推断是不是孤立点的方法还是比較重要的

3、这道题開始的时候全然没有思路。由于一直想的都是“两个点一起删除怎么让连通分支数目最多“,而没有尝试这么思考:”想删一个点,然后在删除一个点“(就是说放一块思考想不出来就一步一步想),也没有这么思考”不知道怎么做决策的时候就枚举“,由于时间12s。足够枚举。我的代码也在6000ms之内跑出来了。

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <algorithm>
  4. #include <iostream>
  5. using namespace std;
  6.  
  7. const int MAXN =5000*2+100;
  8. struct Node
  9. {
  10. int to,next,from;
  11. int u;
  12. }e[MAXN];
  13. int n,m;
  14. int head[MAXN];
  15. int vis[MAXN],son, subset[MAXN],dfn[MAXN],low[MAXN],tmpdfn,first,vv[MAXN],scnt[MAXN];
  16. void init()
  17. {
  18. memset(head,-1,sizeof(head));
  19. for(int i=0;i<n*2+10;i++)e[i].from=-1;
  20. }
  21.  
  22. void addedge(int u,int v,int k)
  23. {
  24. e[k].to=v;
  25. e[k].from=u;
  26. e[k].next=head[u];
  27. //e[k].u=0;
  28. head[u]=k;
  29. }
  30. int rt;
  31. void init2()
  32. {
  33. tmpdfn=0;
  34. memset(subset,0,sizeof(subset));
  35. memset(vis,0,sizeof(vis));
  36. memset(dfn,0,sizeof(dfn));
  37. memset(low,0,sizeof(low));
  38. memset(vv,0,sizeof(vv));
  39. memset(scnt,-1,sizeof(scnt));
  40. }
  41.  
  42. void dfs(int u)
  43. {
  44. dfn[u]=low[u]=++tmpdfn;
  45. for(int j=head[u];j!=-1;j=e[j].next)
  46. {
  47. if(e[j].to!=first)//
  48. {
  49. int v=e[j].to;
  50. if(!vis[v])
  51. {
  52. vis[v]=1;
  53. scnt[v]=rt,vv[rt]++;
  54. dfs(v);
  55. low[u]=min(low[u],low[v]);
  56. if(low[v]>=dfn[u])
  57. {
  58. if(u == rt)son++;
  59. else subset[u]++;
  60. }
  61. }
  62. else
  63. {
  64. low[u]=min(low[u],dfn[v]);
  65. }
  66. }
  67. }
  68. }
  69.  
  70. int solve()
  71. {
  72. int ans=0,cnt=0;
  73. for(int k=0;k<n;k++)
  74. {
  75. //删点
  76. first=k;
  77. init2();
  78. cnt=0;
  79.  
  80. for(int i=0;i<n;i++)
  81. {
  82. if(i!=first)
  83. {
  84. if(!vis[i])
  85. {
  86. son=0;
  87. rt=i;
  88. cnt++;
  89. vis[i]=1;
  90. scnt[rt]=rt,vv[rt]++;
  91. dfs(i);
  92. if(son)subset[rt]=son-1;
  93. }
  94. }
  95. }
  96. int pos=-1,mmax=0;
  97. for(int i=0;i<n;i++)
  98. if(i != first )//ans=max(ans,subset[i]+cnt);//cnt-1+subset[i]+1
  99. {
  100. if(mmax<subset[i]+cnt)
  101. {
  102. pos=i;
  103. mmax=subset[i]+cnt;
  104. }
  105. }
  106. if(vv[scnt[pos]] == 1)mmax--;//不是割点。去掉该点后,连通分支数不会添加
  107. ans=max(ans,mmax);
  108. }
  109. return ans;
  110. }
  111.  
  112. int main()
  113. {
  114. //freopen("hdu4587.txt","r",stdin);
  115. int u,v,k;
  116. while(~scanf("%d%d",&n,&m))
  117. {
  118. init();
  119. for(int i=0,k=0;i<m;i++)
  120. {
  121. scanf("%d%d",&u,&v);
  122. addedge(u,v,k++);
  123. addedge(v,u,k++);
  124. }
  125. printf("%d\n",solve());
  126. }
  127. return 0;
  128. }

hdu 4587 推断孤立点+割点+ 删除点之后,剩下多少连通分量的更多相关文章

  1. HDU 4587 TWO NODES 枚举+割点

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587 TWO NODES Time Limit: 24000/12000 MS (Java/Other ...

  2. HDU 4587 TWO NODES(割点)(2013 ACM-ICPC南京赛区全国邀请赛)

    Description Suppose that G is an undirected graph, and the value of stab is defined as follows: Amon ...

  3. HDU 4587 TWO NODES 割点

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4587 题意: 删除两个点,使连通块的数目最大化 题解: 枚举删除第一个点,然后对删除了第一个点的图跑 ...

  4. hdu 4587(割点的应用)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4587 思路:题目的意思很简单,就是删除任意2个节点以及关联的边,求图的最大连通分量数.我们知道删除割点 ...

  5. HDU - 4587 TWO NODES (图的割点)

    Suppose that G is an undirected graph, and the value of stab is defined as follows: Among the expres ...

  6. hdu 4587 2013南京邀请赛B题/ / 求割点后连通分量数变形。

    题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量. 思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可.算法相对简单,但是注意几个细节: 1:原图可能不连通. 2:有 ...

  7. HDU 4587 TWO NODES(割两个点的最大连通分支数)

    http://acm.hdu.edu.cn/showproblem.php?pid=4587 题意: 给一图,求割去两个点后所能形成的最大连通分支数. 思路: 对于这种情况,第一个只能枚举,然后在删除 ...

  8. HDU 5687 字典树插入查找删除

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5687 2016百度之星资格赛C题,直接套用字典树,顺便巩固了一下自己对字典树的理解 #include< ...

  9. HDU 4587 B - TWO NODES tarjan

    B - TWO NODESTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view ...

随机推荐

  1. RabbitMQ~广播消息

    定义 广播消息是指生产者产生的消息将分发给所有订阅这个消息的消费者,而普通的模式是:一批消息可以被多个人共同消费,如consumer1可能消费1,3,5记录,而consumer2可能消费的是2,4,6 ...

  2. 获取Spring容器中的Bean协助调试

    在使用Spring进行开发时,有时调bug真的是很伤脑筋的一件事,我们可以通过自定义一个监听器来获取Spring容器中的Bean实例来协助我们调试. 第一步:编写自定义监听器 /** * 监听serv ...

  3. C++中图片重命名

    非常简单的小程序,满足自己的需求. #include <iostream> #include <fstream> #include<sstream> using n ...

  4. [ SPOJ RESTACK ] Restacking haybales

    \(\\\) Description 给出一个环,每个位置有一个初值 \(A_i\),有一个目标值 \(B_i\),保证 \(\sum A_i=\sum B_i\) 每个位置只能把值分给隔壁的,每次分 ...

  5. JS简单路由实现

    说一下前端路由实现的简要原理,以 hash 形式(也可以使用 History API 来处理)为例, 当 url 的 hash 发生变化时,触发 hashchange 注册的回调,回调中去进行不同的操 ...

  6. js中原型和原型链

    1.原型: 在JavaScript 中,对象被表现为prototype . 原型其实一直存在于我们接触过的任何一个对象. 2. Tip:在函数对象中也存在__proto__属性,但是查看函数对象的原型 ...

  7. 梦想CAD控件网页版文字样式

    增加文字样式 用户可以增加文字样式到数据库,并设置其字体等属性,具体实现js代码如下: function CreateText(){ //返回控件的数据库对象 var database =mxOcx. ...

  8. (独孤九剑)---PHP操作MySQL数据库

    [一]开启mysql扩展 在PHP操作MySQL数据库之前,要保证开启了MySQL数据库扩展 若未开启,则可以将php.int文件下的php_mysql开启即可,方式为去掉前面的封号; 配置完成后要重 ...

  9. 关于DOS-BOX的使用方法

    将MASM文件夹里的全部文件拷贝到一个目录下,比如E:\masm下,然后将这个目录挂着为DOSBox的一个盘符下,挂载命令为 Mount c e:\masm 切换到E盘 然后编译,运行

  10. shell日志颜色处理

    记录一下shell日志颜色处理 _COLORS=${BS_COLORS:-$(tput colors >/dev/)} __detect_color_support() { # shellche ...