ZJOI2008 骑士(树型DP)
ZJOI2008 骑士
题目大意
给出n个人的战斗力和每个人讨厌的人,然后问最大能有多大的战斗力
solution
简单粗暴的题意,有一丢丢背包的感觉
那敢情就是DP了
有点像没有上司的舞会,,,
根据题意,骑士之间互相厌恶会形成一个环,任务就是找到这个环并且把它断开,然后对断开的两个端点分别求答案,然后取最优结果
设定当前点为u
断开的两个节点是u1和u2
选取当前点的状态记为1,不选的话就是0
那么数组就是dp[u][0],dp[u][1]
从这两个中间取最大值即可
最后将所有的DP值加和就是结果了
第一眼应为想到要找环,所以本来打算写Tarjan判连通块
然后去blogs验证思路的时候发现好像并不需要
用到了一个神奇的东东——拓扑排序
判环,拆分,统计入度和出度
求和得到结果即可
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
inline int read(){
	int x = 0, w = 1;
	char ch = getchar();
	for(; ch > '9' || ch < '0'; ch = getchar()) if(ch == '-') w = -1;
	for(; ch >= '0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
	return x * w;
}
const int N = 1000000 + 10;
int head[N], cnt = 1, size[N], r1, r2,p[N];
struct Edge {
    int to, next;
} edges[N << 1];
bool vis[N], flag;
long long ans, f[N][2];
inline void add(int x, int y) {
    edges[++cnt].next = head[x];
    edges[cnt].to = y;
    head[x] = cnt;
}
inline void dfs(int x, int fa) {
    vis[x] = 1;
    size[++size[0]] = x;
    for (int i = head[x]; i; i = edges[i].next) {
        int v = edges[i].to;
        if (v == fa) continue;
        if (!vis[v]) dfs(v, x);
        else if (vis[v] && !flag) {
            flag = true;
            r1 = x, r2 = v;
        }
    }
}
inline void dfs2(int x, int fa) {
    f[x][0] = 0;
    f[x][1] = p[x];
    for (int i = head[x]; i; i = edges[i].next) {
        int v = edges[i].to;
        if (v && v != fa) {
            dfs2(v, x);
            f[x][1] += f[v][0];
            f[x][0] += max(f[v][0], f[v][1]);
        }
    }
}
inline void solve() {
    if (!flag) {
        int root = size[1];
        dfs2(root, -1);
        ans += max(f[root][0], f[root][1]);
    } else {
        long long maxv = -100;
        for (int i = head[r1]; i; i = edges[i].next) {
            if (edges[i].to == r2) {
                edges[i].to = 0;
                edges[i ^ 1].to = 0;
                break;
            }
        }
        dfs2(r1, -1);
        maxv = max(maxv, f[r1][0]);
        dfs2(r2, -1);
        maxv = max(maxv, f[r2][0]);
        ans += maxv;
    }
}
int n;
int main() {
    n = read();
    int x, y;
    for (int i = 1; i <= n; i++){
        p[i] = read();
        x = read();
        add(x, i);
        add(i, x);
    }
    for (int i = 1; i <= n; i++) {
        if (!vis[i]) {
            size[0] = 0;
            flag = false;
            dfs(i, -1);
            solve();
        }
    }
    printf("%lld", ans);
    return 0;
}
ZJOI2008 骑士(树型DP)的更多相关文章
- BZOJ1040: [ZJOI2008]骑士  树套环DP
		题意:一个图n个点n条边保证点能互相到达,ab有边意味着ab互相厌恶,求一个集合,使得集合里元素最多而且没有人互相厌恶 删去环上一条边树形dp,比如删掉的边连着a,b,那么先dp出不选a的最大值,再d ... 
- BZOJ_1040_[ZJOI2008]骑士_树形DP
		BZOJ_1040_[ZJOI2008]骑士_树形DP 题意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各 界的赞扬.最近发生了一件可怕的事情,邪 ... 
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
		题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ... 
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
		好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ... 
- 【XSY1905】【XSY2761】新访问计划 二分 树型DP
		题目描述 给你一棵树,你要从\(1\)号点出发,经过这棵树的每条边至少一次,最后回到\(1\)号点,经过一条边要花费\(w_i\)的时间. 你还可以乘车,从一个点取另一个点,需要花费\(c\)的时间. ... 
- 洛谷P3354 Riv河流 [IOI2005] 树型dp
		正解:树型dp 解题报告: 传送门! 简要题意:有棵树,每个节点有个权值w,要求选k个节点,最大化∑dis*w,其中如果某个节点到根的路径上选了别的节点,dis指的是到达那个节点的距离 首先这个一看就 ... 
- 【POJ 3140】 Contestants Division(树型dp)
		id=3140">[POJ 3140] Contestants Division(树型dp) Time Limit: 2000MS Memory Limit: 65536K Tot ... 
- Codeforces  581F  Zublicanes and Mumocrates(树型DP)
		题目链接 Round 322 Problem F 题意 给定一棵树,保证叶子结点个数为$2$(也就是度数为$1$的结点),现在要把所有的点染色(黑或白) 要求一半叶子结点的颜色为白,一半叶子结点的 ... 
- ZOJ 3949 (17th 浙大校赛 B题,树型DP)
		题目链接 The 17th Zhejiang University Programming Contest Problem B 题意 给定一棵树,现在要加一条连接$1$(根结点)和$x$的边,求加 ... 
- BZOJ 1564 :[NOI2009]二叉查找树(树型DP)
		二叉查找树 [题目描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小. 另一方面,这棵查找树中每个结点都有一个权值,每个结 ... 
随机推荐
- .Net Core 会逆袭成为最受欢迎开发平台吗?
			本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. .Net Core 是什么? 最新.Net Core 热词霸占了各个 ... 
- win7 64位系统怎么使用debug
			安装DOSbox软件 下载个debug.exe然后把这放到D盘或E盘的根目录下 然后启动dosbox软件,在下面输入 mount c d:\ enter键 c: enter键 输入debug命令就ok ... 
- 数据结构之链表(Linked list)
			说明:如果仔细阅读完全文后,可能感觉有些不统一,这里先说明下原因. 链表尾引用不统一:在介绍单链表时,只有一个链表首部的引用(head) 指向第一个节点.你看到后面关于双链表及循环列表时,除了指向第一 ... 
- 处理npm安装模块报错01
			报错:Error: EACCES: permission denied, mkdir '/usr/local/lib/node_modules/nodemon_tmp' 解决:sudo cnpm in ... 
- airpods2隐藏的使用技巧(十)点
			airpods的凭借出色的外观.不错的音质以及非常人性化的用户体验秒杀了同类型的许多真无线蓝牙耳机,以下是第二代产品airpods2一些使用的技巧,推荐给大家. 一. 随时随地查看airpods2 ... 
- MATLAB实例:多元函数拟合(线性与非线性)
			MATLAB实例:多元函数拟合(线性与非线性) 作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ 更多请看:随笔分类 - MATLAB作图 之前写过一篇博 ... 
- js实现点击切换checkbox背景图片
			在制作网页的过程中,经常需要实现点击切换背景图片的效果,本文关注的是表单中checkbox背景图片切换的实现.如图,在输入用户名和密码后,用户需要选择是否记住密码 图片背景为白色表示未勾选状态 ,背景 ... 
- 基于Python3.7的robotframework环境搭建步骤
			一.前言 Robot Framework作为公司能快速落地实现UI自动化测试的一款框架,同时也非常适合刚入门自动化测试的朋友们去快速学习自动化,笔者计划通过从搭建逐步到完成自动化测试的过程来整体描述它 ... 
- 授权函数-web_set_certificate_ex
			设置证书和密钥文件属性. int web_set_certificate_ex(const char * option_list,LAST); 该函数与Loadrunner 录制设置属性中的Recor ... 
- 厉害了!除了find命令,还有这么多文件查找命令,高手必备!
			大家好,我是良许. 在系统里查找文件,是所有工程师都必备的技能(不管你用的是 Windows .Linux.还是 MacOS 系统).对于 Linux 操作系统,单单一个 find 命令就可以完成非常 ... 
