[ZJOI2008]骑士 DP dfs
题解:
观察题面可以很快发现这是一棵基环内向树(然而并没有什么用。。。)
再稍微思考一下,假设将这个环中的任意一点设为root,然后去掉root到下面的特殊边(即构成环的那条边),那么就构成了一棵树,并且可以用简单树形DP解决。
再考虑加上这条边的限制,设被去掉的这条边是连接root 和 x的, 这条边实际上就是限制了在选root的时候不能选x,那么考虑一个暴力的想法。
我们先在图中dfs,找到这个环,然后任意指定一点为root,再跑两边树形DP,一遍强制不选root,然后跑普通树形DP。另一遍强制选root,然后跑树形DP加上特判不能选x,最后两种答案取max即可。
我这样写可能比较长,别人的做法只要写两遍dfs,我需要3遍(不过后面两个dfs可以复制粘贴)。但实际上是一个思路。别人的做法是dfs找到这个环,然后随便找条环上的边断开,然后强制这条边连接的两个点其中一个不选(其实就和我的写法一样的意思,只不过我是先把这两个点中的一个指定为了root)
#include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 1000100
#define ac 2000100
#define LL long long
int n, m, root;
int s[AC], p[AC], deep[AC];
LL f[AC][], g[AC][], ans;//存下每个点的厌恶对象以方便判断
int Head[AC], date[ac], Next[ac], tot;
bool z[AC], vis[AC], book[AC], flag; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} inline void add(int f, int w)
{
date[++tot] = w, Next[tot] = Head[f], Head[f] = tot;
date[++tot] = f, Next[tot] = Head[w], Head[w] = tot;
} void pre()
{
n = read();
for(R i = ; i <= n; i ++)
{
s[i] = read(), p[i] = read();
add(i, p[i]);
}
deep[] = ;
} void dfs1(int x)//找到反向边的那个点定为root
{
z[x] = true;
int now;
//if(root) return ;
for(R i = Head[x]; i; i = Next[i])
{
now = date[i];
if(z[now] && deep[now] + != deep[x]) root = x;
if(z[now] && p[now] == x && p[x] == now) root = x, flag = true;//特殊情况
//if(root) return ;
if(z[now]) continue;
deep[now] = deep[x] + ;
dfs1(now);
}
} void dfs2(int x)//强制选root
{
int now;
vis[x] = true;
f[x][] = s[x];//初始化
for(R i = Head[x]; i; i = Next[i])
{
now = date[i];
if(vis[now]) continue;
if(now == p[x] && x == root && !flag) continue;
dfs2(now);//忽略这条边,如果是特殊情况则不能忽略,因为是重边,一旦忽略将忽略2条
f[x][] += f[now][];
f[x][] += max(f[now][], f[now][]);
}
if(x == p[root]) f[x][] = f[x][];
} void dfs3(int x)//强制不选root
{
int now;
g[x][] = s[x];
book[x] = true;
for(R i = Head[x]; i; i = Next[i])
{
now = date[i];
if(book[now]) continue;
if(now == p[x] && x == root && !flag) continue;
dfs3(now);
g[x][] += g[now][];
g[x][] += max(g[now][], g[now][]);
}
} void work()
{
for(R i = ; i <= n; i ++)//因为本来就不一定联通,所以要跑多次
if(!z[i])
{
dfs1(i);
dfs2(root);
dfs3(root);
ans += max(f[root][], g[root][]);
}
printf("%lld\n", ans);
}
int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
// fclose(stdin);
return ;
}
[ZJOI2008]骑士 DP dfs的更多相关文章
- BZOJ 1040: [ZJOI2008]骑士 [DP 环套树]
传送门 题意:环套树的最大权独立集 一开始想处理出外向树树形$DP$然后找到环再做个环形$DP$ 然后看了看别人的题解其实只要断开环做两遍树形$DP$就行了...有道理! 注意不连通 然后洛谷时限再次 ...
- bzoj 1040: [ZJOI2008]骑士 環套樹DP
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1755 Solved: 690[Submit][Status] ...
- bzoj 1040: [ZJOI2008]骑士 树形dp
题目链接 1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3054 Solved: 1162[Submit][S ...
- 【洛谷】2607: [ZJOI2008]骑士【树形DP】【基环树】
P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...
- 【BZOJ1040】[ZJOI2008]骑士 树形DP
[BZOJ1040][ZJOI2008]骑士 Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情 ...
- [ZJOI2008]骑士(基环树,树形dp)
[ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...
- BZOJ1040: [ZJOI2008]骑士(奇环树,DP)
题目: 1040: [ZJOI2008]骑士 解析: 假设骑士\(u\)讨厌骑士\(v\),我们在\(u\),\(v\)之间连一条边,这样我们就得到了一个奇环树(奇环森林),既然是一颗奇环树,我们就先 ...
- 「树形DP」洛谷P2607 [ZJOI2008]骑士
P2607 [ZJOI2008]骑士 题面: 题目描述 Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的 ...
- ZJOI2008 骑士(树型DP)
ZJOI2008 骑士 题目大意 给出n个人的战斗力和每个人讨厌的人,然后问最大能有多大的战斗力 solution 简单粗暴的题意,有一丢丢背包的感觉 那敢情就是DP了 有点像没有上司的舞会,,, 根 ...
随机推荐
- ubuntu如何设置Python的版本
Ubuntu默认已经安装了Python的版本了,不过是Python2的版本. 我们安装好Python3想把他切换为系统默认的版本. sudo update-alternatives --config ...
- C# WebClient类上传和下载文件
这篇文章主要介绍了C# WebClient类用法实例,本文讲解使用WebClient下载文件.OpenWriter打开一个流使用指定的方法将数据写入到uri以及上传文件示例,需要的朋友可以参考下 ...
- ECSHOP和SHOPEX快递单号查询国际EMS插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- [转]select top n 动态赋值
怎样实现 select top n 语句中 n 的动态赋值呢?怎样实现 select top n 语句中 n 的动态赋值,求教各位了. 要把这个n值传到存储过程中,再加入 select t ...
- Spark-源码-SparkContext的初始化
Spark版本 1.3SparkContext初始化流程 1.0 在我们的主类 main() 方法中经常会这么写 val conf = new SparkConf().setAppName(" ...
- Python基于jieba的中文词云
今日学习了python的词云技术 from os import path from wordcloud import WordCloud import matplotlib.pyplot as plt ...
- Leecode刷题之旅-C语言/python-88合并两个有序数组
/* * @lc app=leetcode.cn id=88 lang=c * * [88] 合并两个有序数组 * * https://leetcode-cn.com/problems/merge-s ...
- PHP教程专题资源免费下载地址收藏
PHP教程专题资源免费下载地址收藏 PHP,即Hypertext Preprocessor,是一种被广泛应用的开源通用脚本语言,尤其适用于 Web 开发并可嵌入 HTML 中去.它的语法利用了 C. ...
- CSS3新特性回顾
CSS3 介绍 开始实例 新特征简介 强大的CSS选择器 抛弃图片的视觉效果 盒模型变化(多列布局和弹性盒模型) 阴影效果 Web字体和web Font 图标 CSS33过渡与动画交互效果 媒体查询 ...
- python基础之socket套接字基础part2
基于UDP的socket 面向无连接的不可靠数据传输,可以没有服务器端,只不过没有服务器端,发送的数据会被直接丢弃,并不能到达服务器端 1 #客户端 2 import socket 3 ip_port ...