\(\text{Problem}\)

A君和B君在玩一种叫做新红黑树的游戏,即在一棵由红枝和黑枝构成的树上轮流砍树枝,每次砍一枝,A君每次只能砍红枝,B君每次只能砍黑枝,当其中某人已经没有树枝砍的时候,由另外一人砍,直到砍完全部树枝。树枝是带权的,每个人的总分是他砍的树枝的权值之和,那些由于其他树枝被砍掉而与根失去联系的树枝会自动消失。每次由A君先砍,设“D=A君的得分-B君的得分”,A君想让D最大,而B君想让D最小,A君和B君都是极其聪明的人,他们始终以最优策略进行整个游戏,你知道最后的D值是多少吗?

\(1\le n\le 20\)

\(\text{Solution}\)

考虑两个 \(dfs\) 互相暴搜,二进制记录边信息

然后记忆化

以前没打过,今天考场一遍过了?!

比较慢,其实可以预处理删边后同时影响的边的二进制信息

这样就不需要每次删边后再一条一条边的删去子树影响

\(\text{Code}\)

#include <cstdio>
#include <cstring>
#include <vector>
#define RE register
using namespace std; const int N = 25, INF = 2e9;
int n, f[1<<21][2], dep[N];
struct edge{int u, v, c, w;}e[N];
vector<int> g[N]; void prepare(int x, int fa)
{
dep[x] = dep[fa] + 1;
for(RE int i = 0; i < n - 1; i++)
{
if (e[i].u == x && e[i].v ^ fa)
{
prepare(e[i].v, x), g[x].push_back(i);
for(RE int j = 0; j < g[e[i].v].size(); j++) g[x].push_back(g[e[i].v][j]);
}
else if (e[i].v == x && e[i].u ^ fa)
{
prepare(e[i].u, x), g[x].push_back(i);
for(RE int j = 0; j < g[e[i].u].size(); j++) g[x].push_back(g[e[i].u][j]);
}
}
} int dfs1(int s);
int dfs2(int s);
int dfs1(int s)
{
if (f[s][0] != -INF) return f[s][0];
if (s == (1 << n - 1) - 1) return 0;
int ret = -INF, bz = 0;
for(RE int i = 0; i < n - 1; i++)
{
if (((s >> i) & 1) || (e[i].c != 1)) continue;
int ss = (s | (1 << i)), x = e[i].u, y = e[i].v;
if (dep[x] < dep[y]) swap(x, y);
for(RE int j = 0; j < g[x].size(); j++) ss |= (1 << g[x][j]);
ret = max(ret, e[i].w - dfs2(ss)), bz = 1;
}
if (!bz) return -dfs2(s);
return f[s][0] = ret;
}
int dfs2(int s)
{
if (f[s][1] != -INF) return f[s][1];
if (s == (1 << n - 1) - 1) return 0;
int ret = -INF, bz = 0;
for(RE int i = 0; i < n - 1; i++)
{
if (((s >> i) & 1) || (e[i].c != -1)) continue;
int ss = (s | (1 << i)), x = e[i].u, y = e[i].v;
if (dep[x] < dep[y]) swap(x, y);
for(RE int j = 0; j < g[x].size(); j++) ss |= (1 << g[x][j]);
ret = max(ret, e[i].w - dfs1(ss)), bz = 1;
}
if (!bz) return -dfs1(s);
return f[s][1] = ret;
} int main()
{
scanf("%d", &n), ++n;
for(RE int i = 0; i < n - 1; i++)
scanf("%d%d%d%d", &e[i].u, &e[i].v, &e[i].c, &e[i].w), ++e[i].u, ++e[i].v;
prepare(1, 0);
for(RE int i = 0; i < (1 << n - 1); i++) f[i][0] = f[i][1] = -INF;
printf("%d\n", dfs1(0));
}

JZOJ 1075. 【GDKOI2006】新红黑树的更多相关文章

  1. 二叉搜索树、AVL平衡二叉搜索树、红黑树、多路查找树

    1.二叉搜索树 1.1定义 是一棵二叉树,每个节点一定大于等于其左子树中每一个节点,小于等于其右子树每一个节点 1.2插入节点 从根节点开始向下找到合适的位置插入成为叶子结点即可:在向下遍历时,如果要 ...

  2. 红黑树(R-B Tree)

    R-B Tree简介 R-B Tree,全称是Red-Black Tree,又称为“红黑树”,它一种特殊的二叉查找树.红黑树的每个节点上都有存储位表示节点的颜色,可以是红(Red)或黑(Black). ...

  3. Linux CFS调度器之pick_next_task_fair选择下一个被调度的进程--Linux进程的管理与调度(二十八)

    1. CFS如何选择最合适的进程 每个调度器类sched_class都必须提供一个pick_next_task函数用以在就绪队列中选择一个最优的进程来等待调度, 而我们的CFS调度器类中, 选择下一个 ...

  4. Linux进程调度策略的发展和演变--Linux进程的管理与调度(十六)

    1 前言 1.1 进程调度 内存中保存了对每个进程的唯一描述, 并通过若干结构与其他进程连接起来. 调度器面对的情形就是这样, 其任务是在程序之间共享CPU时间, 创造并行执行的错觉, 该任务分为两个 ...

  5. Linux进程调度与抢占

    一.linux内核抢占介绍 1.抢占发生的必要条件 a.preempt_count抢占计数必须为0,不为0说明其它地方调用了禁止抢占的函数,比如spin_lock系列函数.b.中断必须是使能的状态,因 ...

  6. Java 容器 LinkedHashMap源码分析2

    一.类签名 LinkedHashMap<K,V>继承自HashMap<K,V>,可知存入的节点key永远是唯一的.可以通过Android的LruCache了解LinkedHas ...

  7. Linux进程调度策略的发展和演变(转)

    转发:http://blog.csdn.net/gatieme/article/details/51701149  1 前言 1.1 进程调度 内存中保存了对每个进程的唯一描述, 并通过若干结构与其他 ...

  8. Linux 调度器发展简述

    引言 进程调度是操作系统的核心功能.调度器只是是调度过程中的一部分,进程调度是非常复杂的过程,需要多个系统协同工作完成.本文所关注的仅为调度器,它的主要工作是在所有 RUNNING 进程中选择最合适的 ...

  9. sicily 题目分类

    为了方便刷题,直接把分类保存下来方便来找. 转自:http://dengbaoleng.iteye.com/blog/1505083 [数据结构/图论] 1310Right-HeavyTree笛卡尔树 ...

  10. linux内核中的数据结构

    http://vinllen.com/linuxnei-he-zhong-de-shu-ju-jie-gou/ https://zhuanlan.zhihu.com/p/58087261 https: ...

随机推荐

  1. windows环境变量修改器

    软件及源码 前言 我一直再用win7的系统,当更改path环境变量的时候很难受, 就只能看到一段,然后前面有啥后面有啥都看不到,而且来回调整优先级的时候需要剪切粘贴,主要就是来回调节优先级特别麻烦.所 ...

  2. python opencv制作隐藏图片

    前言 隐藏图片就是在白色背景和黑色背景显示出不同的图片,之前qq可以显示,现在好像也不行了,原因就是原来的qq,在发出来默认是白色背景,而点开后是黑色背景.但是这个原理还是挺有意思的,所以简单的研究了 ...

  3. SSH(一)架包的引入

    一年多未使用了,有些东西真的会忘. 一.ssh的图形化记忆运作流程 二.Struts2.hibernate.spring需要引用的jar包 Struts2: 基本开发:struts-2.3.32\ap ...

  4. jmeter ORA-00911: invalid character报错解决方法

    今天通过jmeter进行Oracle数据库操作时,遇到一个小坑. 解决办法:去掉sql最后的分号.

  5. Servlet面试题合集

    servlet的生命周期 在创建servlet对象时,通过调用.init()方法进行初始化 通过service()方法来接收客户端的请求.根据请求方式的不同转发给对应的doGet()或doPost() ...

  6. Dart开发服务端,我是不是发烧(骚)了?

    前言 最近一段时间,我和我的团队开发了两个 APP. 客户端方面采用了 Flutter,方便跨平台. 服务端方面剑走偏锋,没有采用 php, pythod, java之类的,而是采用了与 Flutte ...

  7. Burp Suite进阶

    1.Scanner Burp Scanner主要用于自动检测Web系统的各种漏洞. 首先,确认Burp Suite正常启动并完成浏览器代理的配置.然后进入Burp Proxy,关闭拦截代理功能,快速浏 ...

  8. 侦察工具——Httrack

    前言 web渗透学习笔记,实验环境为Metasploitable靶机上的DVWA.此随笔介绍Web渗透侦察工具Httrack Httrack 简介 Httrack能够克隆拷贝目标网站上的所有可访问.可 ...

  9. [whk] 解三元一次方程

    注:本篇运用大量 Katex ,如果炸了可能是运存不够也可能还要加载一会,重进几次即可.(都2202了,居然还存在我这种会炸公式的笔记本) 前言 写这篇随笔的由来是今天学习了: 不共线三点确定二次函数 ...

  10. [论文总结] kmeans聚类和WGCNA

    kmeans聚类和WGCNA 文章目录 kmeans聚类和WGCNA 论文1 论文2 论文3 总结 总结了3篇论文中kmeans聚类和WGCNA的运用. 论文1 Comprehensive disse ...