题没什么好说的,因为是模板题。求值我用的是dfs。

不能直接在原图上dfs,因为原图上有环的话会发生一些滑稽的事情。所以我们要用Tarjan缩点。因为此题点权全为正,所以如果在图上走一个环当然可以全走一遍,结果当然是更优的。于是可以把环当成一个点来dfs,把它们的点权都加起来当成一个大点。

然后就是求值。原图已经变成一张有向无环图,所以可以用拓扑排序求值,也可以枚举每个还没有被dfs到的点,然后dfs统计答案。dfs的时间是O(n),因为每个点最多被遍历一次。

代码如下

  1. #include<cstdio>
  2. #include<cctype>
  3. #include<cstdlib>
  4.  
  5. inline long long read(){
  6. long long num=,f=;
  7. char ch=getchar();
  8. while(!isdigit(ch)){
  9. if(ch=='-')f=-;
  10. ch=getchar();
  11. }
  12. while(isdigit(ch)){
  13. num=num*+ch-'';
  14. ch=getchar();
  15. }
  16. return num*f;
  17. }
  18.  
  19. struct Edge{
  20. int next,to;
  21. };
  22. struct Pic{
  23. Edge edge[];
  24. int head[],num;
  25. inline void add(int from,int to){
  26. edge[++num]=(Edge){head[from],to};
  27. head[from]=num;
  28. }
  29. }Old,New;
  30. int ans;
  31. int f[];
  32. int val[];
  33. int que[];
  34. int dfn[];
  35. int low[];
  36. int col[];
  37. bool vis[];
  38. int stack[];
  39. int ID,top,cnt;
  40. void tarjan(int x){
  41. dfn[x]=low[x]=++ID;
  42. vis[x]=;
  43. stack[++top]=x;
  44. for(int i=Old.head[x];i;i=Old.edge[i].next){
  45. int to=Old.edge[i].to;
  46. if(!dfn[to]){
  47. tarjan(to);
  48. low[x]=low[x]<low[to]?low[x]:low[to];
  49. }
  50. else if(vis[to]) low[x]=low[x]<dfn[to]?low[x]:dfn[to];
  51. }
  52. if(low[x]==dfn[x]){
  53. vis[x]=;
  54. col[x]=++cnt;
  55. val[cnt]+=que[x];
  56. while(stack[top]!=x){
  57. col[stack[top--]]=cnt;
  58. val[cnt]+=que[stack[top+]];
  59. vis[stack[top+]]=;
  60. }
  61. top--;
  62. }
  63. }
  64.  
  65. int dfs(int x){
  66. if(f[x])return f[x];
  67. f[x]=val[x];
  68. int maxx=;
  69. for(int i=New.head[x];i;i=New.edge[i].next){
  70. int to=New.edge[i].to;
  71. if(!f[to])dfs(to);
  72. maxx=maxx>f[to]?maxx:f[to];
  73. }
  74. f[x]+=maxx;
  75. return f[x];
  76. }
  77.  
  78. int main(){
  79. int n=read(),m=read();
  80. for(int i=;i<=n;++i)que[i]=read();
  81. int from,to;
  82. for(int i=;i<=m;++i){
  83. from=read();to=read();
  84. Old.add(from,to);
  85. }
  86. for(int i=;i<=n;++i)if(!dfn[i])tarjan(i);
  87. for(int i=;i<=n;++i){
  88. for(int j=Old.head[i];j;j=Old.edge[j].next) if(col[i]!=col[Old.edge[j].to]) New.add(col[i],col[Old.edge[j].to]);
  89. }
  90. for(int i=;i<=cnt;++i)
  91. if(!f[i]){
  92. dfs(i);
  93. ans=ans>f[i]?ans:f[i];
  94. }
  95. printf("%d",ans);
  96. }

【Luogu】P3387缩点(Tarjan缩点+深搜DP)的更多相关文章

  1. luogu P3387 【模板】缩点

    题目 好久没法博客了 这次就水个板子题目吧 tarjan缩点之后重新建图 而且边权应该都是正的(要不我怎么能这么轻松水过去) 在新图上记忆化一下就好了 f[i] 表示 开头选i这个点 的 路径最大值 ...

  2. LUOGU P3387 【模板】缩点 (缩点+DAG dp)

    解题思路 缩点后按拓扑排序跑一个dp. #include<iostream> #include<cstdio> #include<cstring> #include ...

  3. 解题报告+板子:luogu P3387 【模板】缩点

    题目链接:P3387 [模板]缩点 缩点板子,所谓\(dp\)就是拓扑排序(毕竟可以重走边),像\(SPFA\)一样松弛就好,就是重边极其烦人,还加了排序(绝对自己想的,然鹅拓扑的思路不是). 下面上 ...

  4. 深搜+DP剪枝 codevs 1047 邮票面值设计

    codevs 1047 邮票面值设计 1999年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond 题目描述 Description ...

  5. luogu P3387 【模板】缩点_拓扑排序

    还是很好些的. Code: #include <stack> #include <cstdio> #include <algorithm> #include < ...

  6. 3.滑雪-深搜&dp

    //Michael喜欢滑雪百这并不奇怪, 因为滑雪的确很刺激.可是为了获得速度,滑的区域必须向下倾斜,而且当你滑到坡底,你不得不再次走上坡或者等待升降机来载你.Michael想知道载一个区域中最长底滑 ...

  7. Tarjan&&缩点简析

    由于昨天写计蒜客初赛的一道题,看出了是缩点,但一时忘记了另外一个叫什么s...的算法怎么写了,话说我为什么没有回去翻一下自己的blog然后今天就去学了更实用也更强力的Tarjan Tarjan的思想其 ...

  8. tarjan缩点(洛谷P387)

    此题解部分借鉴于九野的博客 题目分析 给定一个 \(n\) 个点 \(m\) 条边有向图,每个点有一个权值,求一条路径,使路径经过的点权值之和最大.你只需要求出这个权值和. 允许多次经过一条边或者一个 ...

  9. 【Luogu P3387】缩点模板(强连通分量Tarjan&拓扑排序)

    Luogu P3387 强连通分量的定义如下: 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶 ...

随机推荐

  1. List 集合中数据不重复的使用

    foreach (DataRow dr in dt.Rows) { list.Add(dr["项目组"].ToString()); } list = list.Distinct&l ...

  2. 关于一个app中数据库的问题

    如果是不同名字的数据库,可以有多个数据库操作dao 如果是同样名字的数据库,只能有一个数据库操作dao,创建表的语句可以写在一个oncreate方法里面 例如 public class Address ...

  3. import 何时使用 "" 和<> Objective-C

    Objective-C在这方面与C/C ++相似.引号是给local本地包含的文件的.(你需要指明相对现有文件的相对路径的).而对于尖括号来说,是一个全局路径. 一般情况下引号用在引用自己项目中的类的 ...

  4. c#将本地文件上传至服务器(内网)

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

  5. CPP-网络/通信:COM

    ))//打开串口 { ) { CloseCom();//关闭串口 break; } //添加处理代码. } //最后关闭串口 CloseCom();//关闭串口

  6. Perl 使用哈希的引用

    $ref = \%hash_clomnname_linevalue; $hash_of_whole_table{$table_name} = {%$ref};

  7. 毛毛虫组【Beta】Scrum Meeting 3

    第三天 日期:2019/6/25 前言 第三次会议: 时间:6月25日 地点:教10-A511 内容:此次会议主要是对项目验收做准备工作. 1.1 今日完成任务情况以及遇到的问题. 今日完成任务情况: ...

  8. please upgrade your plan to create a new private reposiory

    请升级你的计划来创建一个新的私人仓库 提交仓库到github,要公开,除非买他们服务,所以把勾去掉就好了keep this code private

  9. -bash: xx: command not found 在有yum源情况下处理

    -bash: xx: command not found 在有yum源情况下处理 yum provides "*/xx"  ###"xx"代表某命令 或者 yu ...

  10. 搭建pip源

    1.安装pip软件 yum -y install python-pippip install --upgrade pippip install pip2pi 2.安装apacheyum -y inst ...