传送门1
传送门2

思路:
好题
比较简单的DP思路
之前没写过基环树DP,第一次搞真心orz
我们发现这些元素是具有从属关系的
也就是说如果对”厌恶的骑士”两两相互连边,那么问题就变成了”在图中找出若干个点,使其两两之间没有直接的连边且点权和最大“
首先我们可以从简单问题入手,把图换成树,然后就发现这是一个简单的O(n)O(n)树形DP
同时我们发现这个图是一棵树+一条边,实际上这是一个基环外向树,即一个环上有若干棵子树
那怎么办呢?
考虑去掉一条环上的边e(u,v)
这不就成了一棵树了吗
只要限制一下(u,v)不能同时选就可以了
这里可以枚举下不选u和不选v的情况,然后取较大值就可以了
……
但是直接这样做可能只能得20分
为什么呢?
因为这个图它不一定是联通的
也就是说,它是由若干个基环外向树组成的,它们是互补联通的……
也就是说我们要对每个基环外向树做DP……
所以说枚举所有点,找完一次环就DP一次就可以了
说白了就是要找出所有的联通块……
Ps:感谢reflash的无私帮助
代码:

#include<cstdio>
#include<iostream>
#define M 1000004
#define LL long long
using namespace std;
int n,tot=1,s,t,del,eg;
int a[M],first[M];
bool vis[M];
LL f[M][2];
struct edge{int v,next;
}e[M<<1];
int in()
{int t=0;char ch=getchar();while (ch>'9'||ch<'0') ch=getchar();while (ch>='0'&&ch<='9') t=(t<<1)+(t<<3)+ch-48,ch=getchar();return t;
}
void add(int x,int y)
{e[++tot]=(edge){y,first[x]};first[x]=tot;e[++tot]=(edge){x,first[y]};first[y]=tot;
}
void dp(int x,int fa)
{f[x][0]=0;f[x][1]=a[x];for (int i=first[x];i;i=e[i].next)if (e[i].v!=fa&&i!=eg&&i!=(eg^1)){dp(e[i].v,x);if (e[i].v!=del)f[x][1]+=f[e[i].v][0],f[x][0]+=max(f[e[i].v][1],f[e[i].v][0]);elsef[x][1]+=f[e[i].v][0],f[x][0]+=f[e[i].v][0];}
}
void find(int x,int fa)
{vis[x]=1;for (int i=first[x];i;i=e[i].next)if (e[i].v!=fa)if (vis[e[i].v])s=x,t=e[i].v,eg=i;elsefind(e[i].v,x);
}
main()
{n=in();for (int i=1;i<=n;++i)a[i]=in(),add(i,in());for (int i=1;i<=n;++i)if (!vis[i]){LL tmp=0;s=0;t=0;eg=0;del=0;find(i,0);if (s){del=s;dp(i,0);if (s!=i)tmp=max(max(f[i][0],f[i][1]),tmp);elsetmp=max(f[i][0],tmp);}if (t){del=t;dp(i,0);if (t!=i)tmp=max(max(f[i][0],f[i][1]),tmp);  elsetmp=max(f[i][0],tmp);}if (!s&&!t) dp(i,0),tmp=max(f[i][0],f[i][1]);f[0][0]+=tmp;}printf("%lld",f[0][0]);
}

【BZOJ1040】【codevs1423】骑士,第一次的基环外向树DP相关推荐

  1. 洛谷 2921 记忆化搜索 tarjan 基环外向树

    洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...

  2. Directed Roads CodeForces - 711D (基环外向树 )

    ZS the Coder and Chris the Baboon has explored Udayland for quite some time. They realize that it co ...

  3. 【暖*墟】#动态规划# 基环树DP的学习与练习

    因为弃置了 四边形不等式优化 ,所以DP的任务还剩下 基环树DP / 插头DP / 动态DP 当然,树形DP / 状压DP / 数位DP / 斜率优化DP 也还是要练习的...... 一 . 基环树的 ...

  4. 基环树DP(bzoj 1040: [ZJOI2008]骑士)

    树:n个点n-1条边的连通图 基环树:n个点n条边的连通图,也就是一个环套着多棵树 基环树DP:找到环上任意相邻两点,断掉这两点之间的边,就形成了一棵树 之后对这两点分别进行一次树形DP即可 例题: ...

  5. BZOJ1040: [ZJOI2008]骑士

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 5332  Solved: 2023 [Submit][Stat ...

  6. [BZOJ2125]最短路(圆方树DP)

    题意:仙人掌图最短路. 算法:圆方树DP,$O(n\log n+Q\log n)$ 首先建出仙人掌圆方树(与点双圆方树的区别在于直接连割边,也就是存在圆圆边),然后考虑点u-v的最短路径,显然就是:在 ...

  7. 51nod1812树的双直径(换根树DP)

    传送门:http://www.51nod.com/Challenge/Problem.html#!#problemId=1812 题解:头一次写换根树DP. 求两条不相交的直径乘积最大,所以可以这样考 ...

  8. P1295 [TJOI2011]书架(线段树dp)

    P1295 [TJOI2011]书架(线段树dp) 我好菜 先考虑普通dp: d p i = m i n ( d p j + m a x ( h j + 1 , h j + 2 - , h i ) ) ...

  9. 【BZOJ1124】Mafia(POI2008)-环套树DP

    测试地址:Mafia 做法: 本题需要用到环套树DP. 按照题目构图,很显然是我们很熟悉的环套树森林.接下来我们进行分析,最后活下来一些什么人是合法的呢?观察发现,一个人的目标如果是自己那就必死,而没 ...

最新文章

  1. [UWP小白日记-10]程序启动屏(ios解锁既视感)
  2. SDN的转发与控制分离—Vecloud微云
  3. oracle查询某个用户下的所有视图
  4. Python中List的复制(直接复制、浅拷贝、深拷贝)
  5. 2018企业面试总汇(答案请自行搜罗) 新增19年阿里面题(反向拓展技术栈)
  6. .Net Core分布式部署中的DataProtection密钥安全性
  7. Jenkins自定义主题
  8. python用法查询笔记_Python爬虫学习笔记(三)
  9. bat转exe工具 Bat To Exe Converter v2.4.7 绿色版
  10. DevOps是敏捷在软件开发团队的另一应用
  11. 【Beta】Phylab 测试报告
  12. c语言转意字符 s,第2章 C语言初探:12、C语言转义字符
  13. oracle日期处理完全版
  14. js基础-23-websocket和ajax的区别
  15. xp自带打印驱动相关
  16. matlab零阶保持器法求z变换,由于和零阶保持器z变换法类似的原因.PPT
  17. RTL8153B RTL8153 千兆以太网 有~现 ~货
  18. Java注解:@IntDef 替换 Emum
  19. u检验中的查u界值表_u检验、t检验、F检验、X2检验
  20. delphi webservice 内存释放_2020年7月——内存天梯图

热门文章

  1. cr全称是什么意思_轻生未遂?她到底经历了些什么......
  2. python scrapy框架爬虫_Python Scrapy爬虫框架
  3. dijkstra伪代码翻译java,Dijkstra算法的伪代码和C语言版本,还是模版
  4. 链家信息python
  5. MacOS录屏OBS+Loopback配置方法
  6. LeetCode-226. 翻转二叉树
  7. switch VS if else
  8. 为php-fpm安装pdo pgsql驱动支持
  9. note_maven的基本使用
  10. php 获取config,PHP MVC如何自动调用config?