题意:给出一个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<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; #define ll long long const int maxn=1e6+; struct Node
{
int to,next;
}e[maxn<<],e2[maxn<<];
int val[maxn];
int head[maxn];
bool vis[maxn];
int head2[maxn];
ll dp[maxn][];
int sb[],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]=;
for(int i=head[x];i;i=e[i].next)
{
int v=e[i].to;
if(v!=fa)
{
if(vis[v])
{
sb[]=x,sb[]=v;
continue;
}
add2(v,x);add2(x,v);
find_sb(v,x);
}
}
} void dfs(int x,int fa)
{
dp[x][]=(ll)val[x];dp[x][]=0ll;
for(int i=head2[x];i;i=e2[i].next)
{
int v=e2[i].to;
if(v!=fa)
{
dfs(v,x);
dp[x][]+=max(dp[v][],dp[v][]);
dp[x][]+=dp[v][];
} }
} int main()
{
int n,x;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%d%d",&val[i],&x);
add(x,i),add(i,x);
}
ll ans=;
for(int i=;i<=n;i++)
{
if(!vis[i])
{
sb[]=sb[]=;find_sb(i,-);
dfs(sb[],-);ll now=dp[sb[]][];
dfs(sb[],-);ans+=max(now,dp[sb[]][]);
}
}
printf("%lld",ans);
return ;
}

题目分享Y的更多相关文章

  1. 题目分享E 二代目

    题意:一棵点数为n的树,每个节点有点权,要求在树中中找到一个最小的x,使得存在一个点满足max(该点点权,该点相邻的点的点权+1,其他点的点权+2)=x 分析:首先要能把题目转化为上述题意 首先题目让 ...

  2. 题目分享D 二代目

    题意:给定一个T条边的无向图,求S到E恰好经过N条边的最短路径 T≤100 N≤1000000 分析:(据说好像假期学长讲过) 首先很容易想到的是dp[i][j][k]表示从i到j经过k条边的最短路径 ...

  3. 题目分享X

    题意:一张票有n位数,如果这张票的前一半数字的和等于后一半数字的和(n一定是偶数),就称这张票为快乐票.有些数被擦除了,标记为’?’(’?‘的个数也是偶数),现在Monocarp 和 Bicarp 进 ...

  4. 题目分享V

    题意:现在两个人做游戏,每个人刚开始都是数字1,谁赢了就能乘以k^2,输的乘以k(k可以是任意整数,每次不一定相同)现在给你最终这两个人的得分,让你判断是否有这个可能,有可能的话Yes,否则No. 分 ...

  5. 题目分享T

    题意:蛐蛐国里现在共有n只蚯蚓(n为正整数).每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n),并保证所有的长度都是非负整数(即:可 能存在长度为0的蚯蚓).每一秒,神刀手会 ...

  6. 题目分享P

    题意: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始,双方轮流进行 操作.当一方操作时,他们需要先选择一个不为根的 ...

  7. 2019年腾讯PHP程序员面试题目分享

    有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群​jq.qq.com 1. php 的垃圾回收机制 PHP 可以自动进行内存管理,清除 ...

  8. 20190924-LeetCode解数独题目分享

    解决数独 题目描述 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以 ...

  9. 题目分享H 二代目

    题意:有m个限制,每个限制l1,r1,l2,r2四个数,限制了一个长度为n的数第l1到r1位要与第l2到r2相同,保证r1-l1=r2-l2,求在限制下一共有多少种数 分析: 暴力的话肯定是从l1-r ...

随机推荐

  1. 一个不错的博客-涉及el 、jstl、log4j 入门等

    http://www.cnblogs.com/Fskjb/category/198224.html

  2. java web之Filter详解

    java web之Filter详解 2012-10-20 0 个评论 作者:chenshufei2 收藏 我要投稿 .概念: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,W ...

  3. 【three.js第三课】鼠标事件,移动、旋转物体

    1.下载three.js的源码包后,文件夹结构如下: 2.在[three.js第一课]的代码基础上,引入OrbitControls.js文件,此文件主要用于 对鼠标的操作. 该文件位置:在文件结构中 ...

  4. C - Dr. Evil Underscores CodeForces - 1285D 二进制

    题目大意:n个数,任意整数x对这n个数取异或值,然后使最大值最小. 思路:数据范围最大为pow(2,30);所以考虑二进制的话,最多有30位.对于某一位d,然后考虑数组v中每一个元素的d为是0还是1, ...

  5. 关于树的重心--POJ 1655

    树的重心的定义: 在一棵树中,找到一个点,其所有的子树中最大的子树节点数最少,那么这个点就是这棵树的重心,删去重心后,生成的多棵树尽可能平衡. 通俗来说就是以这个点为根节点,找到他最大的衣蛾子树,然后 ...

  6. 黑猫关键词URL采集工具 Pro v1.0

    功能介绍:黑猫关键词URL采集工具 Pro v1.0 批量关键词自动搜索采集 自动去除垃圾二级泛解析域名 可设置是否保存域名或者url 联系客服QQ:944520563

  7. 实现一个简单的基于动态代理的 AOP

    实现一个简单的基于动态代理的 AOP Intro 上次看基于动态代理的 AOP 框架实现,立了一个 Flag, 自己写一个简单的 AOP 实现示例,今天过来填坑了 目前的实现是基于 Emit 来做的, ...

  8. Linux学习笔记(二)文件操作命令

    文件操作命令 touch stat cat more less head tail ln touch 英文原意: change file timestamps 功能: 修改文件的时间戳 语法: tou ...

  9. [YII2] 去除自带js,加载自己的JS,然后ajax(json)传值接值!

    本想用YII2自带的JS,可是用着效果不好,想从新加载,找了好多终于实现啦!还有ajax(json)传值接值! 首先直接了当的就把YII2自带的js去掉! 把下面代码加入到/config/main.p ...

  10. Websec level 30

    前言 昨天在易霖博搞的网络安全与执法竞赛看到的一道web题,实际上就是用两个原题凑起来的.. 不过后面的一关没见过这里简单记录一下 第一关 打开是个登录界面,和BJDCTF的简单注入一模一样,连密码都 ...