强连通分量,看大神的题解才会写的....

http://www.cnblogs.com/kuangbin/p/3261157.html

数据量有点大,第一次Submit 2995ms过的,时限3000ms,差一点就TLE了。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<cmath>
  4. #include<algorithm>
  5. #include<vector>
  6. using namespace std;
  7.  
  8. const int maxn = + ;
  9. int N, M;
  10. vector<int>Cun[maxn];
  11. vector<int>G[maxn];
  12. vector<int>FG[maxn];
  13. int nx, ny, Time, Block;
  14. int g[maxn][maxn];
  15. int cx[maxn], cy[maxn];
  16. int mk[maxn];
  17. int flag[maxn], dfn[maxn], Belong[maxn];
  18. struct Point
  19. {
  20. int id, dfn;
  21. } point[maxn];
  22.  
  23. int Scan()
  24. {
  25. int res = , ch, flag = ;
  26.  
  27. if ((ch = getchar()) == '-') //判断正负
  28. flag = ;
  29.  
  30. else if (ch >= '' && ch <= '') //得到完整的数
  31. res = ch - '';
  32. while ((ch = getchar()) >= '' && ch <= '')
  33. res = res * + ch - '';
  34.  
  35. return flag ? -res : res;
  36. }
  37.  
  38. bool cmp(const Point&a, const Point&b)
  39. {
  40. return a.dfn>b.dfn;
  41. }
  42.  
  43. int path(int u)
  44. {
  45. for (int v = ; v <= ny; v++)
  46. {
  47. if (g[u][v] && !mk[v])
  48. {
  49. mk[v] = ;
  50. if (cy[v] == - || path(cy[v]))
  51. {
  52. cx[u] = v;
  53. cy[v] = u;
  54. return ;
  55. }
  56. }
  57. }
  58. return ;
  59. }
  60.  
  61. int MaxMatch()
  62. {
  63. int res = ;
  64. memset(cx, -, sizeof(cx));
  65. memset(cy, -, sizeof(cy));
  66. for (int i = ; i <= nx; i++)
  67. {
  68. if (cx[i] == -)
  69. {
  70. memset(mk, , sizeof(mk));
  71. res = res + path(i);
  72. }
  73. }
  74. return res;
  75. }
  76.  
  77. void dfs(int now)
  78. {
  79. flag[now] = ;
  80. for (int i = ; i<G[now].size(); i++)
  81. if (!flag[G[now][i]])
  82. dfs(G[now][i]);
  83. Time++;
  84. dfn[now] = Time;
  85. }
  86.  
  87. void Dfs(int now)
  88. {
  89. Belong[now] = Block;
  90. for (int i = ; i<FG[now].size(); i++)
  91. if (!Belong[FG[now][i]])
  92. Dfs(FG[now][i]);
  93. }
  94.  
  95. int main()
  96. {
  97. int CA;
  98. CA = Scan();
  99. for (int er = ; er <= CA; er++){
  100. N = Scan();
  101. M = Scan();
  102. memset(flag, , sizeof(flag));
  103. memset(dfn, , sizeof(dfn));
  104. memset(Belong, , sizeof(Belong));
  105. Time = , Block = ;
  106. for (int i = ; i<maxn; i++) G[i].clear();
  107. for (int i = ; i<maxn; i++) Cun[i].clear();
  108. for (int i = ; i<maxn; i++) FG[i].clear();
  109. memset(g, , sizeof(g));
  110. nx = N, ny = M;
  111.  
  112. for (int i = ; i <= N; i++)
  113. {
  114. int ToT, To;
  115. ToT = Scan();
  116. while (ToT--)
  117. {
  118. To = Scan();
  119. Cun[i].push_back(To);
  120. g[i][To] = ;
  121. }
  122. sort(Cun[i].begin(), Cun[i].end());
  123. }
  124. int res = MaxMatch();
  125.  
  126. memset(g, , sizeof(g));
  127. int A = M - res, B = N - res;//A表示虚拟王子数量,B表示虚拟妹子数量
  128. nx = N + A, ny = M + B;
  129. if (B>)//王子有单身
  130. {
  131. for (int j = M + ; j <= M + B; j++)
  132. for (int i = ; i <= N; i++)
  133. {
  134. g[i][j] = ;
  135. G[i].push_back(j + nx);
  136. FG[j + nx].push_back(i);
  137. }
  138. }
  139. if (A>)
  140. {
  141. for (int i = N + ; i <= N + A; i++)
  142. for (int j = ; j <= M; j++)
  143. {
  144. g[i][j] = ;
  145. G[i].push_back(j + nx);
  146. FG[j + nx].push_back(i);
  147. }
  148. }
  149. for (int i = ; i <= N; i++)
  150. for (int j = ; j<Cun[i].size(); j++)
  151. {
  152. g[i][Cun[i][j]] = ;
  153. G[i].push_back(Cun[i][j] + nx);
  154. FG[Cun[i][j] + nx].push_back(i);
  155. }
  156. MaxMatch();
  157. for (int i = ; i <= ny; i++)
  158. if (cy[i] != -)
  159. {
  160. G[i + nx].push_back(cy[i]);
  161. FG[cy[i]].push_back(i + nx);
  162. }
  163.  
  164. for (int i = ; i <= nx + ny; i++) if (!dfn[i]) dfs(i);
  165. for (int i = ; i<nx + ny; i++) point[i].id = i + , point[i].dfn = dfn[i + ];
  166. sort(point, point + nx + ny, cmp);
  167. for (int i = ; i<nx + ny; i++)
  168. if (!Belong[point[i].id])
  169. Block++, Dfs(point[i].id);
  170. int RT;
  171. int ans[maxn];
  172. printf("Case #%d:\n", er);
  173. for (int i = ; i <= N; i++)
  174. {
  175. RT = ;
  176. for (int j = ; j<Cun[i].size(); j++)
  177. {
  178. if (Belong[i] == Belong[Cun[i][j] + nx])
  179. {
  180. ans[RT] = Cun[i][j];
  181. RT++;
  182. }
  183. }
  184. printf("%d", RT);
  185. for (int x = ; x<RT; x++) printf(" %d", ans[x]);
  186. printf("\n");
  187. }
  188. }
  189. return ;
  190. }

HDU 4685 Prince and Princess的更多相关文章

  1. HDU 4685 Prince and Princess 二分图匹配+tarjan

    Prince and Princess 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4685 Description There are n pri ...

  2. HDU 4685 Prince and Princess (2013多校8 1010题 二分匹配+强连通)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  3. HDU 4685 Prince and Princess(二分图+强连通分量)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4685 题意:给出n个王子和m个公主.每个王子有一些自己喜欢的公主可以匹配.设最大匹配为M.那么对于每个 ...

  4. hdu 4685 Prince and Princess(匈牙利算法 连通分量)

    看了别人的题解.须要用到匈牙利算法的强连通算法 #include<cstdio> #include<algorithm> #include<vector> #pra ...

  5. HDU 4685 Prince and Princess(二分匹配+强联通分量)

    题意:婚配问题,但是题目并不要求输出最大匹配值,而是让我们输出,一个王子可以与哪些王妃婚配而不影响最大匹配值. 解决办法:先求一次最大匹配,如果有两个已经匹配的王妃,喜欢她们两个的有两个或者以上相同的 ...

  6. Prince and Princess HDU - 4685(匹配 + 强连通)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  7. HDU4685:Prince and Princess(二分图匹配+tarjan)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  8. 强连通+二分匹配(hdu4685 Prince and Princess)

    Prince and Princess Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  9. POJ 1904 HDU 4685

    这两道题差不多,POJ这道我很久以前就做过,但是比赛的时候居然没想起来.. POJ 这道题的题意是,N个王子每个人都有喜欢的公主,当他们选定一个公主结婚时,必须是的剩下的人也能找到他喜欢的公主结婚. ...

随机推荐

  1. alertview 添加图片

    - (void)willPresentAlertView:(UIAlertView *)alertView { 在这个方法中, 绘制需要的东西 uiview *myView = [uiview all ...

  2. 【Python之路】第一篇--Linux基础命令

    pwd 命令 查看”当前工作目录“的完整路径 pwd -P # 显示出实际路径,而非使用连接(link)路径:pwd显示的是连接路径 .   表示当前目录 ..  表示上级目录 /  表示根目录 ls ...

  3. Hibernate查询、连接池、二级缓存

    Hibernate第三天: 1. 对象状态 2. session缓存 3. lazy懒加载 4. 映射 一对一对映射 组件/继承映射 目标: 一.hibernate查询 二.hibernate对连接池 ...

  4. Hadoop上的中文分词与词频统计实践 (有待学习 http://www.cnblogs.com/jiejue/archive/2012/12/16/2820788.html)

    解决问题的方案 Hadoop上的中文分词与词频统计实践 首先来推荐相关材料:http://xiaoxia.org/2011/12/18/map-reduce-program-of-rmm-word-c ...

  5. HDU 3338 Kakuro Extension

    网络最大流 TLE了两天的题目.80次Submit才AC,发现是刘汝佳白书的Dinic代码还可以优化.....瞬间无语..... #include<cstdio> #include< ...

  6. hdu_5787_K-wolf Number(数位DP)

    题目链接:hdu_5787_K-wolf Number 题意: 给你一个区间,让你找满足任意k个数位内都没有相同的数字的个数 题解: 因为k不大,就直接将当前pos的前k-1个数传进去就行了 #inc ...

  7. form异步无刷新提交,提交后可以显示弹出框,否则弹出框会被刷新不见,使用 preventDefault

    出错点:确认按钮上.加onclick事件.每次点击都会追加给form追加on监听方法.累加on方法,重复提交 suppress_exception:true 阻止异常 (百度推送 jdk) 向下按 p ...

  8. ADT(abstract data types)抽象数据类型

    1.What is it? An abstract data type is a set of objects together with a set of operations. 抽象数据类型是带有 ...

  9. R语言笔记4--可视化

    接R语言笔记3--实例1 R语言中的可视化函数分为两大类,探索性可视化(陌生数据集,不了解,需要探索里面的信息:偏重于快速,方便的工具)和解释性可视化(完全了解数据集,里面的故事需要讲解别人:偏重全面 ...

  10. js获取url传递参数,js获取url?号后面的参数

    方法一.正则表达式 function getQueryString(name) { var reg = new RegExp("(^|&)" + name + " ...