[题目链接]

https://www.lydsy.com/JudgeOnline/problem.php?id=1040

[算法]

首先 , 题目中互相讨厌的关系构成了一棵基环森林

用拓扑排序找出环 , 对于每个环上的点为根节点 , 做以下DP :

f[u][0]表示以u为根的子树中 , 不选u , 最大战斗力是多少 , f[u][1]表示选u , 最大战斗力是多少

显然 :

f[u][0] = sigma{max{f[v][0] , f[v][1]})

f[u][1] = a[u] + sigma{f[v][0]}

然后在环上再次DP即可

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000010
typedef long long LL;
const LL inf = 1e18; struct edge
{
int to , nxt;
} e[MAXN << ]; int n , tot , cnt;
int head[MAXN] , deg[MAXN] , a[MAXN] , c[MAXN];
LL f[MAXN][] , dp[MAXN][];
bool vis[MAXN];
LL ans , res; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
T f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
inline void addedge(int u , int v)
{
++tot;
e[tot] = (edge){v , head[u]};
head[u] = tot;
}
inline void topsort()
{
queue< int > q;
for (int i = ; i <= n; i++)
{
if (deg[i] == )
q.push(i);
}
while (!q.empty())
{
int cur = q.front();
q.pop();
for (int i = head[cur]; i; i = e[i].nxt)
{
int v = e[i].to;
if ((--deg[v]) == )
q.push(v);
}
}
}
inline void treedp(int u , int fa)
{
f[u][] = ;
f[u][] = a[u];
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (v == fa || vis[v]) continue;
treedp(v , u);
f[u][] += max(f[v][] , f[v][]);
f[u][] += f[v][];
}
}
inline void dfs(int u)
{
c[++cnt] = u;
vis[u] = true;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!vis[v] && deg[v] > ) dfs(v);
}
} int main()
{ read(n);
for (int i = ; i <= n; i++)
{
read(a[i]);
int fa;
read(fa);
addedge(i , fa);
addedge(fa , i);
++deg[i]; ++deg[fa];
}
topsort();
for (int u = ; u <= n; u++)
{
if (!vis[u] && deg[u] > )
{
cnt = ;
dfs(u);
} else continue;
for (int i = ; i <= cnt; i++) treedp(c[i] , -);
ans = max(f[c[]][] , f[c[]][]);
for (int i = ; i <= cnt; i++) dp[i][] = dp[i][] = -inf;
dp[][] = f[c[]][];
for (int i = ; i <= cnt; i++)
{
dp[i][] = dp[i - ][] + f[c[i]][];
dp[i][] = max(dp[i - ][] , dp[i - ][]) + f[c[i]][];
}
chkmax(ans , max(dp[cnt][] , dp[cnt][]));
for (int i = ; i <= cnt; i++) dp[i][] = dp[i][] = -inf;
dp[][] = f[c[]][];
for (int i = ; i < cnt; i++)
{
dp[i][] = dp[i - ][] + f[c[i]][];
dp[i][] = max(dp[i - ][] , dp[i - ][]) + f[c[i]][];
}
chkmax(ans , max(dp[cnt - ][] , dp[cnt - ][]) + f[c[cnt]][]);
res += ans;
}
printf("%lld\n" , res); return ; }

[ZJOI 2008] 骑士的更多相关文章

  1. BZOJ 1040 ZJOI 2008 骑士 基环树林+树形DP

    题目大意:有一些骑士.他们每个人都有一个权值.可是因为一些问题,每个骑士都特别讨厌还有一个骑士.所以不能把他们安排在一起.求这些骑士所组成的编队的最大权值和是多少. 思路:首先貌似是有向图的样子,可是 ...

  2. BZOJ 1040 ZJOI 2008 骑士 树形DP

    题意: 有一些战士,他们有战斗力和讨厌的人,选择一些战士,使他们互不讨厌,且战斗力最大,范围1e6 分析: 把战士看作点,讨厌的关系看作一条边,连出来的是一个基环树森林. 对于一棵基环树,我们找出环, ...

  3. BZOJ 1040 (ZJOI 2008) 骑士

    题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争.战火绵延五百里, ...

  4. 【BZOJ 1038】【ZJOI 2008】瞭望塔

    http://www.lydsy.com/JudgeOnline/problem.php?id=1038 半平面交裸题,求完半平面后在折线段上的每个点竖直向上和半平面上的每个点竖直向下求距离,统计最小 ...

  5. 【BZOJ 1036】【ZJOI 2008】树的统计 树链剖分模板题

    sth神犇的模板: //bzoj1036 题目:一个n个点的树每个点有一个权值,支持修改单点权值,求某两点路径上的点权和或最大点权. #include <cstdio> using nam ...

  6. [ZJOI 2008]泡泡堂BNB

    Description 题库链接 双方 \(n\) 人,给出每人的战斗力,赢一场加 \(2\) 分,平局 \(1\) 分,失败不得分.求最大和最小的得分. \(1\leq n\leq 100000\) ...

  7. 【BZOJ 1036】【ZJOI 2008】树的统计Count

    http://www.lydsy.com/JudgeOnline/problem.php?id=1036 复习了一下好写好调的lct模板啦啦啦--- #include<cstdio> #i ...

  8. 【ZJOI 2008】树的统计

    [题目链接] 点击打开链接 [算法] 树链剖分模板题 [代码] #include<bits/stdc++.h> using namespace std; #define MAXN 3000 ...

  9. 【ZJOI 2008】 生日聚会

    [题目链接] 点击打开链接 [算法] 动态规划 f[i][j][x][y]表示当前选了i个男生,j个女生,男生与女生差最大为x,女生与男生差最大为y的方案数 转移很显然,笔者不再赘述 [代码] #in ...

随机推荐

  1. 数据库设计三范式(3NF)

    问:当时你数据库是如何设计的? 答:当时是按照三范式规范设计的: 第一范式: 1:数据库的原子性,即保证数据库表的每一列都不可分割的 第二范式: 1:原子性,即保证数据库表的每一列都不可分割 2:表中 ...

  2. File类 文件过滤器

    创建过滤器 package cn.zmh.File; import java.io.File; import java.io.FileFilter; // 实现FileFilter类的功能 publi ...

  3. DICOM医学图像显示算法改进与实现——LUT

    引言 随着Ul(超声成像).CT(计算机断层成像).MRI(核磁共振成像).CR(计算机X线成像).电子内窥镜.盯(正电子发射断层成像)和MI(分子影像)等医学影像设备不断涌现,利用计算机对医学影像设 ...

  4. 搭建企业内部DNS服务器,docker 部署内部 dnsmasq

    获取镜像 docker pull jpillora/dnsmasq 配置域名 # http://oss.segetech.com/intra/srv/dnsmasq.conf #log all dns ...

  5. Vue 基础

    1. data 数据 methods 方法 watch 监听变化 2. 模版指令(类似 angular) {{}} v-text 渲染数据 v-html html 结构 3. v-if v-show ...

  6. 01背包+卡精度 Hdu 2955

    <span style="color:#3333ff;">/* ---------------------------------------------------- ...

  7. Redis相关知识

    Redis 存储的五种 字符串类型:string 一个String类型的value最大可以存储512M String是最常用的一种数据类型,普通的key/value存储. 散列类型:  hash 键值 ...

  8. linux getopt函数详解

    getopt(分析命令行参数)   表头文件 #include<unistd.h> 定义函数 int getopt(int argc,char * const argv[ ],const ...

  9. js操作文件 HTML5版

    js操作文件 HTML5版,有需要的朋友可以参考下. <!DOCTYPE html> <html> <head> <title>JSFileReader ...

  10. appium-java-api

    AppiumDriver getAppStrings() 默认系统语言对应的Strings.xml文件内的数据. driver.getAppStrings(String language) 查找某一个 ...