题意:给个有向图,每个人可以投票(可以投很多人,一次一票),但是一个人只能支持一人一次,支持可以传递,自己支持自己不算,被投支持最多的人。

开始想到缩点,然后搜索,问题是有一点想错了!以为支持按票数计算,而不是按人数!还各种树形dp/搜索求可以到达边数。。提交WA了。。。

又反复读了题目之后才发现。。错误。。只要人数就行。。。问题简单了许多。。。

缩点成有向无环图后:每个SCC中支持的人数就是scc里面的人,要求可到达的点最多的点,当然要放过来求方便:反向图那个点可以到达的点最多!于是建反向图直接dfs即可,记录答案有点麻烦。。。提交就A了。。。这题总体花了我2多个小时。。算失败。。。

  1. #include<iostream>
  2. #include<stack>
  3. #include<queue>
  4. #include<cstdio>
  5. #include<cstring>
  6. #include<vector>
  7. #include<algorithm>
  8. using namespace std;
  9. const int inf=0x3f3f3f3f;
  10. const int maxv=5005,maxe=50005;
  11. int nume=0;int head[maxv];int e[maxe][3];
  12. void inline adde(int i,int j,int c)
  13. {
  14. e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
  15. e[nume++][2]=c;
  16. }
  17. int dfn[maxv];int low[maxv];int vis[maxv];int ins[maxv]; stack<int>sta;
  18. int scc[maxv];int numb=0;int times=0;
  19. int n,m; int sccsize[maxv];
  20. void tarjan(int u)
  21. {
  22. dfn[u]=low[u]=times++;
  23. ins[u]=1;
  24. sta.push(u);
  25. for(int i=head[u];i!=-1;i=e[i][1])
  26. {
  27. int v=e[i][0];
  28. if(!vis[v])
  29. {
  30. vis[v]=1;
  31. tarjan(v);
  32. if(low[v]<low[u])low[u]=low[v];
  33. }
  34. else if(ins[v]&&dfn[v]<low[u])
  35. {
  36. low[u]=dfn[v];
  37. }
  38. }
  39. if(low[u]==dfn[u])
  40. {
  41. numb++;int counted=0;
  42. int cur;
  43. do
  44. {
  45. cur=sta.top();
  46. sta.pop();
  47. ins[cur]=0;
  48. scc[cur]=numb;
  49. counted++;
  50. }while(cur!=u);
  51. sccsize[numb]=counted;
  52. }
  53. }
  54. struct pi
  55. {
  56. int id;
  57. int w;
  58. };
  59. bool my (pi a,pi b)
  60. {
  61. if(a.w!=b.w)
  62. return a.w>b.w;
  63. else
  64. return a.id<b.id;
  65. }
  66. int sums=0;
  67. vector<vector<int> >e2(maxv+1);
  68. int ind[maxv];
  69. void dfs(int u)
  70. {
  71. for(int i=0;i<e2[u].size();i++)
  72. {
  73. int v=e2[u][i];
  74. if(!vis[v])
  75. {
  76. vis[v]=1;
  77. sums+=sccsize[v];
  78. dfs(v);
  79. }
  80. }
  81. }
  82. vector<int>sumss;
  83. void solve()
  84. {
  85. for(int i=0;i<n;i++)
  86. {
  87. if(!vis[i])
  88. {
  89. vis[i]=1;
  90. tarjan(i);
  91. }
  92. }
  93. for(int i=0;i<n;i++)
  94. for(int j=head[i];j!=-1;j=e[j][1])
  95. {
  96. int v=e[j][0];
  97. if(scc[i]!=scc[v])
  98. {
  99. e2[scc[v]].push_back(scc[i]);
  100. ind[scc[i]]++;
  101. }
  102. }
  103. int minsums=0;
  104. vector<pi>ans;
  105. for(int i=1;i<=numb;i++)
  106. {
  107. sums=0;
  108. memset(vis,0,sizeof(vis));
  109. if(ind[i]==0)
  110. {
  111. vis[i]=1;
  112. sums+=sccsize[i]-1;
  113. dfs(i);
  114. if(sums>=minsums)
  115. {
  116. pi tp;
  117. tp.w=sums;
  118. tp.id=i;
  119. ans.push_back(tp);
  120. minsums=sums;
  121. }
  122. }
  123. }
  124. vector<int>realans;
  125. for(int i=0;i<ans.size();i++)
  126. {
  127. if(ans[i].w==minsums)
  128. {
  129. realans.push_back(ans[i].id);
  130. }
  131. }
  132. for(int j=0;j<realans.size();j++)
  133. for(int i=0;i<n;i++)
  134. {
  135. if(scc[i]==realans[j])
  136. {
  137. sumss.push_back(i);
  138. }
  139. }
  140. sort(sumss.begin(),sumss.end());
  141. printf("%d\n",minsums);
  142. for(int i=0;i<sumss.size();i++)
  143. {
  144. if(i!=sumss.size()-1)
  145. printf("%d ",sumss[i]);
  146. else
  147. printf("%d\n",sumss[i]);
  148. }
  149. }
  150. void read_build()
  151. {
  152. int aa,bb,cc;
  153. for(int i=0;i<m;i++)
  154. {
  155. scanf("%d%d",&aa,&bb);
  156. adde(aa,bb,0);
  157. }
  158. }
  159. void init()
  160. {
  161. numb=times=nume=0;
  162. sumss.clear();
  163. for(int i=0;i<maxv;i++)
  164. {
  165. head[i]=-1;
  166. ins[i]=dfn[i]=low[i]=scc[i]=vis[i]=0;
  167. sccsize[i]=0;
  168. ind[i]=0;
  169. e2[i].clear();
  170. }
  171. }
  172. int main()
  173. {
  174. int T;
  175. scanf("%d",&T);
  176. int ct=1;
  177. while(T--)
  178. {
  179. scanf("%d%d",&n,&m);
  180. init();
  181. read_build();
  182. printf("Case %d: ",ct++);
  183. solve();
  184. }
  185. return 0;
  186. }

hdu 3639 有向图缩点+建反向图+搜索的更多相关文章

  1. hdu 3072 有向图缩点成最小树形图计算最小权

    题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费.求最小费用. 有向图缩点(无需建立新图,,n<=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新 ...

  2. hdu 1827 有向图缩点看度数

    题意:给一个有向图,选最少的点(同时最小价值),从这些点出发可以遍历所有. 思路:先有向图缩点,成有向树,找入度为0的点即可. 下面给出有向图缩点方法: 用一个数组SCC记录即可,重新编号,1.... ...

  3. HDU 3639 Hawk-and-Chicken(强连通分量+缩点)

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013480600/article/details/32140501 HDU 3639 Hawk-a ...

  4. HDU 4635 (完全图 和 有向图缩点)

    题目链接:HDU  4635 题目大意: 给你一个有向图,加有向边,使得这个图是简单有向图.问你最多加多少条有向边. 简单有向图: 1.不存在有向重边. 2.不存在图循环.(注意是不存在 “图” 循环 ...

  5. HDU 1045 Fire Net(行列匹配变形+缩点建图)

    题意:n*n的棋盘上放置房子.同一方同一列不能有两个,除非他们之间被墙隔开,这种话. 把原始图分别按行和列缩点 建图:横竖分区.先看每一列.同一列相连的空地同一时候看成一个点,显然这种区域不可以同一时 ...

  6. HDU 3639 Hawk-and-Chicken(良好的沟通)

    HDU 3639 Hawk-and-Chicken 题目链接 题意:就是在一个有向图上,满足传递关系,比方a->b, b->c,那么c能够得到2的支持,问得到支持最大的是谁,而且输出这些人 ...

  7. 对Tarjan——有向图缩点算法的理解

    开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...

  8. hdu 4778 Gems Fight! 博弈+状态dp+搜索

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4102743.html 题目链接:hdu 4778 Gems Fight! 博弈+状态dp+搜 ...

  9. hdoj 3861 The King’s Problem【强连通缩点建图&&最小路径覆盖】

    The King’s Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. Codeforces Round #461 (Div. 2) D. Robot Vacuum Cleaner

    D. Robot Vacuum Cleaner time limit per test 1 second memory limit per test 256 megabytes Problem Des ...

  2. Linux系统属性文件详解

    1)inode概述 中文意思就是索引节点(index node)第一部分是inode 第二部分是block inode主要用来存放文件属性信息的(也就是ls - l 的结果)包含的属性信息包括文件的大 ...

  3. linux系统下单节点hadoop2的配置

    Jdk安装: jdk-7u45-linux-x64.gz cp jdk-7u45-linux-x64.gz /usr/java/ cd /usr/java/ tar -zxvf jdk-7u45-li ...

  4. luogu1829 [国家集训队]Crash的数字表格

    被 bs 了姿势水平--好好学习数学QAQQAQQAQ ref #include <iostream> #include <cstring> #include <cstd ...

  5. ckeditor添加日历控件

    这里日历控件用的是开源的My97DatePicker,先看下效果图: 1.点击左侧自定义的日历控件按钮,弹出日历控件对话框. 2.点击确定,日历控件添加的表单设计器中,同时保留日历的控件样式 3.点击 ...

  6. ios开发学习笔记001-C语言基础知识

    先来学习一下C语言基础知识,总结如下: 在xcode下编写代码. 1.编写代码 2.编译:cc –c 文件名.c 编译成功会生成一个 .o的目标文件 3.链接:把目标文件.o和系统自带的库合并在一起, ...

  7. c#中dynamic ExpandoObject的用法

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. [DM8168]Linux下控制GPIO实现LED流水灯

    首先加载驱动模块,应用程序通过调用API实现GPIO控制功能. 驱动程序: /* * fileName: led_gpio.c * just for LED GPIO test * GP1_14 -& ...

  9. [转]/dev/null 命令用法

    /dev/null :代表空设备文件 :代表重定向到哪里,例如:echo "123" > /home/123.txt 1 :表示stdout标准输出,系统默认值是1,所以&q ...

  10. maven国内镜像

    <?xml version="1.0" encoding="UTF-8"?> <!--Licensed to the Apache Softw ...