题意:对于一个有向图,问最大团中有多少点,要求该点集内所有点对间至少有一条路径(u到v或v到u或两条都有)。

首先,对于每一个强连通分量,其中的所有点必然能够互相到达,所以先进行缩点,然后对于缩点后的 DAG,dp[i] 表示从 i 强连通分量开始能够到达的最多的点数,那么在缩点时需要记录一下每个强连通分量的点数。然后进行DP,初始值定为该强连通分量的点数,然后用它能到达的点来更新它本身。取最大值就行了。

  1. #include<stdio.h>
  2. #include<string.h>
  3. #include<stack>
  4. #include<queue>
  5. using namespace std;
  6.  
  7. const int maxn=;
  8. const int maxm=;
  9.  
  10. int head[][maxn],point[][maxm],nxt[][maxm],size[];
  11. int n,t,scccnt;
  12. int stx[maxn],low[maxn],scc[maxn],num[maxn],dp[maxn];
  13. stack<int>S;
  14.  
  15. void init(){
  16. memset(head,-,sizeof(head));
  17. size[]=size[]=;
  18. memset(dp,,sizeof(dp));
  19. }
  20.  
  21. void add(int a,int b,int c=){
  22. point[c][size[c]]=b;
  23. nxt[c][size[c]]=head[c][a];
  24. head[c][a]=size[c]++;
  25. }
  26.  
  27. void dfs(int s){
  28. stx[s]=low[s]=++t;
  29. S.push(s);
  30. for(int i=head[][s];~i;i=nxt[][i]){
  31. int j=point[][i];
  32. if(!stx[j]){
  33. dfs(j);
  34. low[s]=min(low[s],low[j]);
  35. }
  36. else if(!scc[j]){
  37. low[s]=min(low[s],stx[j]);
  38. }
  39. }
  40. if(low[s]==stx[s]){
  41. scccnt++;
  42. while(){
  43. int u=S.top();S.pop();
  44. scc[u]=scccnt;
  45. num[scccnt]++;
  46. if(s==u)break;
  47. }
  48. }
  49. }
  50.  
  51. void setscc(){
  52. memset(stx,,sizeof(stx));
  53. memset(scc,,sizeof(scc));
  54. memset(num,,sizeof(num));
  55. t=scccnt=;
  56. for(int i=;i<=n;++i)if(!stx[i])dfs(i);
  57. for(int i=;i<=n;++i){
  58. for(int j=head[][i];~j;j=nxt[][j]){
  59. int k=point[][j];
  60. if(scc[i]!=scc[k]){
  61. add(scc[i],scc[k],);
  62. }
  63. }
  64. }
  65. }
  66.  
  67. void dfs1(int s){
  68. if(dp[s])return;
  69. dp[s]=num[s];
  70. for(int i=head[][s];~i;i=nxt[][i]){
  71. int j=point[][i];
  72. dfs(j);
  73. if(num[s]+dp[j]>dp[s])dp[s]=num[s]+dp[j];
  74. }
  75. }
  76.  
  77. int main(){
  78. int T;
  79. scanf("%d",&T);
  80. while(T--){
  81. int m;
  82. scanf("%d%d",&n,&m);
  83. init();
  84. while(m--){
  85. int a,b;
  86. scanf("%d%d",&a,&b);
  87. add(a,b);
  88. }
  89. setscc();
  90. int ans=;
  91. for(int i=;i<=scccnt;++i){
  92. dfs1(i);
  93. if(ans<dp[i])ans=dp[i];
  94. }
  95. printf("%d\n",ans);
  96. }
  97. return ;
  98. }

UVA11324 强连通+dp记忆化搜索的更多相关文章

  1. 【bzoj5123】[Lydsy12月赛]线段树的匹配 树形dp+记忆化搜索

    题目描述 求一棵 $[1,n]$ 的线段树的最大匹配数目与方案数. $n\le 10^{18}$ 题解 树形dp+记忆化搜索 设 $f[l][r]$ 表示根节点为 $[l,r]$ 的线段树,匹配选择根 ...

  2. 【BZOJ】1415 [Noi2005]聪聪和可可 期望DP+记忆化搜索

    [题意]给定无向图,聪聪和可可各自位于一点,可可每单位时间随机向周围走一步或停留,聪聪每单位时间追两步(先走),问追到可可的期望时间.n<=1000. [算法]期望DP+记忆化搜索 [题解]首先 ...

  3. [题解](树形dp/记忆化搜索)luogu_P1040_加分二叉树

    树形dp/记忆化搜索 首先可以看出树形dp,因为第一个问题并不需要知道子树的样子, 然而第二个输出前序遍历,必须知道每个子树的根节点,需要在树形dp过程中记录,递归输出 那么如何求最大加分树——根据中 ...

  4. poj1664 dp记忆化搜索

    http://poj.org/problem?id=1664 Description 把M个相同的苹果放在N个相同的盘子里,同意有的盘子空着不放,问共同拥有多少种不同的分法?(用K表示)5.1.1和1 ...

  5. 状压DP+记忆化搜索 UVA 1252 Twenty Questions

    题目传送门 /* 题意:给出一系列的01字符串,问最少要问几个问题(列)能把它们区分出来 状态DP+记忆化搜索:dp[s1][s2]表示问题集合为s1.答案对错集合为s2时,还要问几次才能区分出来 若 ...

  6. ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. Poor Ramzi -dp+记忆化搜索

    ACM International Collegiate Programming Contest, Tishreen Collegiate Programming Contest (2017)- K. ...

  7. POJ 1088 DP=记忆化搜索

    话说DP=记忆化搜索这句话真不是虚的. 面对这道题目,题意很简单,但是DP的时候,方向分为四个,这个时候用递推就好难写了,你很难得到当前状态的前一个真实状态,这个时候记忆化搜索就派上用场啦! 通过对四 ...

  8. zoj 3644(dp + 记忆化搜索)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4834 思路:dp[i][j]表示当前节点在i,分数为j的路径条数,从 ...

  9. loj 1044(dp+记忆化搜索)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=26764 思路:dp[pos]表示0-pos这段字符串最少分割的回文 ...

随机推荐

  1. IBInspectable / IBDesignable

    无论陈词滥调多少次,比起一个需要我们记住并且输入什么的界面来说,如果替换成我们能够看见并可控制的界面的话将会是巨大的进步. Xcode 6 提供了这样一个替代,在旧技术上建立新的互动.在设计项目的时候 ...

  2. APP store 上架过程中碰到的那些坑&被拒的各种奇葩原因整理&审核指南中文版

    苹果官方发布的十大常见被拒原因 1.崩溃次数和Bug数量.苹果要求开发者在将应用提交给App Store之前彻查自己的应用,以尽量避免Bug的存在. 2.链或错误的链接.应用中所有的链接必须是真实且有 ...

  3. SAP 中如何寻找增强

    http://blog.csdn.net/edifierliu/article/details/5978824 查找SAP标准事务代码中使用的BADI: 在SE24中,查看类对象CL_EXITHAND ...

  4. sql 如何把查询得到的结果如何放入一个新表中

    如何把这个查询到的结果放到一张新表中? 2014-03-13 15:26   提问者采纳   表已经存在:insert into 表名 (列名1... 列名n) select 列名1....列名n f ...

  5. BZOJ 3439 Kpm的MC密码

    倒着建trie,然后主席树来求子树第k大. #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  6. 学习笔记:js、css、html判断浏览器的各种版本

    js.css.html判断浏览器的各种版本 (转载自:http://www.jb51.net/web/42244.html  版权归原作者所有) 利用正则表达式来判断ie浏览器版本 判断是否IE浏览器 ...

  7. Math中floor,round和ceil的区别

    floor 返回不大于的最大整数 round 则是4舍5入的计算,入的时候是到大于它的整数(当-1.5时可见,四舍五入后得到的结果不是我们期待的,解决办法是先对他取绝对值,然后在用round方法) r ...

  8. LeetCode Combinations (DFS)

    题意: 产生从1-n的k个数的所有组合,按升序排列并返回. 思路: DFS一遍即可解决.注意升序. class Solution { public: vector<vector<int&g ...

  9. 'dict' object has no attribute 'a'

    a = {} #a.a = 'a' #AttributeError: 'dict' object has no attribute 'a' #a['a'] #KeyError: 'a' a['a'] ...

  10. Sonar + Jacoco,强悍的UT, IT 双覆盖率统计(转)

    以前做统计代码测试覆盖,一般用Cobertura.以前统计测试覆盖率,一般只算Unit Test,或者闭上眼睛把Unit Test和Integration Test一起算. 但是,我们已经过了迷信UT ...