热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

题目分享Y

题意:给出一个n个点n条边的图且不一定连通(原题面为每个节点出度为1),相邻节点不能同时被选,每个节点有其对应价值,求最多能获得多少价值?n

题意:给出一个n个点n条边的图且不一定连通(原题面为每个节点出度为1),相邻节点不能同时被选,每个节点有其对应价值,求最多能获得多少价值?n<=1e6,val[i]<=1e6

分析:很容易想到,如果这个图是n个点n-1条边而且连通的话,那么这个图肯定是一棵树,这用树形dp是很好实现的

dp[x][0]表示x节点不选,其子树(包括x)能产生的最大价值

dp[x][1]表达x节点选,其子树(包括x)能产生的最大价值

那么dp[x][0]+=max(dp[v][1],dp[v][0])

dp[x][1]+=dp[v][0],其中v是x的儿子

那么如果这个题是n个点n条边而且连通的话,那么这个图不就是一棵树再连上一条边,显然会是该图上得到一个环

看到环,我们之前的第一反应肯定是要缩点,但在这题中我们需要做的是将该图转化成树,也就是在环上任意位置断一条边(把这个思路积累下来吧,以前估计没做过类似做法的题)

首先在换上任意断一条边显然是不会使图不连通的,因为断开位置的两个端点依然可以利用环的剩余部分连接

那么再考虑这题的性质,设这两个断开位置的点为a,b

显然,选a的时候是不能选b的,选b的时候是不能选a的

我们在断开这条边的时候,这两个点的关系在树的意义上已经不相连了,也就是说上面那条性质也就无法实现了

所以我们必须要手动实现那条性质,

实现的方法有很多,比较朴素的就是dp[x][0/1]变成dp[x][0/1][0/1][0/1]后面两个0/1分别表示ab两点是否被选,这显然是可以做的,不过略有些复杂

可以考虑我们树中最有标志性的点或者是最易辨识的点显然是根节点

如果我们将a或b设为根节点是不是会更容易计算

注意这里设为根节点并不意味着a,b会被选

假如我们不别的限制,单纯用a为根得到完整的dp数组

显然dp[a][0]表示a不选而b可选可不选,a的子树及其自身的最大价值

dp[a][1]表示a选而b可选可不选,a的子树及其自身的最大价值

显然第二种是可能有违反那条性质的情况存在的(a选b也选),所以dp[a][1]其实对答案没啥帮助

而dp[a][0]又不能包含所有情况(他只包含a不选的情况,没有a选的情况)

所以我们需要再以b为根节点计算dp值

同理dp[b][1]是要舍掉的,

如果将ab选不选表示为0/1 0/1的话

dp[a][0]就是00和01

dp[b][0]就是00和10

而我们所需要的值是00,01和10中的最大值

这里00被计算两遍没啥影响

所以答案就是max(dp[a][0],dp[b][0])注意,这里a和b分别是以a,b为根的结果需要分开求

再回到该题上

这个图不一定连通啊

所以可能有多个这样的图(树+一条边),

那有没有可能出现树+两条边或者树呢?

不可能,因为不要光看这是一个n个点n条边的图

原题上每个节点的出度是1

也就是说,对于任意一个连通子图,他一定有节点个数条边,也就是我们说的树+一条边结构

如果出现树或树+两条边的话,显然则会出现n个点n-1条边的连通子图或者n个点n+1条边的连通子图,这就与题意不符了

所以我们需要对于每个树+一条边的结构干上述过程,然后把每个max加起来

还有我这里断边采用的是重新建图,一开始我写了个判断,但一直wa,你们也可以写写试试,教一下我这个ljQAQ

记得开longlong

代码:


#include
#include

#include

using namespace std;
#define ll long long
const int maxn=1e6+1;
struct Node
{
int to,next;
}e[maxn
<<1],e2[maxn<<1];
int val[maxn];
int head[maxn];
bool vis[maxn];
int head2[maxn];
ll dp[maxn][
2];
int sb[2],cnt,cnt2;
void add(int x,int y)
{
e[
++cnt].to=y;
e[cnt].next
=head[x];
head[x]
=cnt;
}
void add2(int x,int y)
{
e2[
++cnt2].to=y;
e2[cnt2].next
=head2[x];
head2[x]
=cnt2;
}
void find_sb(int x,int fa)
{
vis[x]
=1;
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
if(vis[v])
{
sb[
0]=x,sb[1]=v;
continue;
}
add2(v,x);add2(x,v);
find_sb(v,x);
}
}
}
void dfs(int x,int fa)
{
dp[x][
1]=(ll)val[x];dp[x][0]=0ll;
for(int i=head2[x];i;i=e2[i].next)
{
int v=e2[i].to;
if(v!=fa)
{
dfs(v,x);
dp[x][
0]+=max(dp[v][0],dp[v][1]);
dp[x][
1]+=dp[v][0];
}

}
}
int main()
{
int n,x;
scanf(
"%d",&n);
for(int i=1;i<=n;i++)
{
scanf(
"%d%d",&val[i],&x);
add(x,i),add(i,x);
}
ll ans
=0;
for(int i=1;i<=n;i++)
{
if(!vis[i])
{
sb[
0]=sb[1]=0;find_sb(i,-1);
dfs(sb[
0],-1);ll now=dp[sb[0]][0];
dfs(sb[
1],-1);ans+=max(now,dp[sb[1]][0]);
}
}
printf(
"%lld",ans);
return 0;
}

 


推荐阅读
  • Manacher算法详解:寻找最长回文子串
    本文将详细介绍Manacher算法,该算法用于高效地找到字符串中的最长回文子串。通过在字符间插入特殊符号,Manacher算法能够同时处理奇数和偶数长度的回文子串问题。 ... [详细]
  • 解决SQL Server数据库sa登录名无法连接的问题
    在安装SQL Server数据库后,使用Windows身份验证成功,但使用SQL Server身份验证时遇到问题。本文将介绍如何通过设置sa登录名的密码、启用登录名状态以及开启TCP协议来解决这一问题。 ... [详细]
  • 如果应用程序经常播放密集、急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了。因为MediaPlayer存在如下缺点:1)延时时间较长,且资源占用率高 ... [详细]
  • [c++基础]STL
    cppfig15_10.cppincludeincludeusingnamespacestd;templatevoidprintVector(constvector&integer ... [详细]
  • 自动验证时页面显示问题的解决方法
    在使用自动验证功能时,页面未能正确显示错误信息。通过使用 `dump($info->getError())` 可以帮助诊断和解决问题。 ... [详细]
  • Framework7:构建跨平台移动应用的高效框架
    Framework7 是一个开源免费的框架,适用于开发混合移动应用(原生与HTML混合)或iOS&Android风格的Web应用。此外,它还可以作为原型开发工具,帮助开发者快速创建应用原型。 ... [详细]
  • 本文介绍了如何使用 CMD 批处理脚本进行文件操作,包括将指定目录下的 PHP 文件重命名为 HTML 文件,并将这些文件复制到另一个目录。 ... [详细]
  • 两个条件,组合控制#if($query_string~*modviewthread&t(&extra(.*)))?$)#{#set$itid$1;#rewrite^ ... [详细]
  • 本文详细介绍了DMA控制器如何通过映射表处理来自外设的请求,包括映射表的设计和实现方法。 ... [详细]
  • 本文介绍了 NOI Open Judge 6049 购书问题的详细解法,代码简洁易懂,并附有详细的注释和解释。 ... [详细]
  • 本文介绍了多种开源数据库及其核心数据结构和算法,包括MySQL的B+树、MVCC和WAL,MongoDB的tokuDB和cola,boltDB的追加仅树和mmap,levelDB的LSM树,以及内存缓存中的一致性哈希。 ... [详细]
  • MySQL初级篇——字符串、日期时间、流程控制函数的相关应用
    文章目录:1.字符串函数2.日期时间函数2.1获取日期时间2.2日期与时间戳的转换2.3获取年月日、时分秒、星期数、天数等函数2.4时间和秒钟的转换2. ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • poj 3352 Road Construction ... [详细]
  • 2.2 组件间父子通信机制详解
    2.2 组件间父子通信机制详解 ... [详细]
author-avatar
手机用户2502900625
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有