[题目链接]

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. 洛谷—— P1605 迷宫

    P1605 迷宫 题目背景 迷宫 [问题描述] 给定一个N*M方格的迷宫,迷宫里有T处障碍,障碍处不可通过.给定起点坐标和 终点坐标,问: 每个方格最多经过1次,有多少种从起点坐标到终点坐标的方案.在 ...

  2. mybatis注解@selectKey对于db2数据库的使用

    在新增时返回当前新增的主键. 数据库:DB2 用的是mybatis的@selectKey 代码: @InsertProvider(type = Test.class,method="inse ...

  3. Go -- 通过GOTRACEBACK生成程序崩溃后core文件的方法(gcore gdb)

    写一个错误的c程序   package dlsym import "testing" func Test_intercept(t *testing.T) { Intercept(& ...

  4. 30 分钟编写一个 Flask 应用

    Flask 是一种很赞的Python web框架.它极小,简单,最棒的是它很容易学. 今天我来带你搭建你的第一个Flask web应用!和官方教程 一样,你将搭建你自己的微博客系统:Flaskr.和官 ...

  5. Microsoft Dynamics CRM Server 2013软件安装要求

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveV9mMTIz/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...

  6. SQL server创建和管理

    数据库函数的应用 数据库的查询方法 修改和替换数据库的数据

  7. nginx-伤心的事

    今天测试接口,总是出问题,测试了两天,整个流程就卡在最后一步. 每次采用curl,request等请求访问我的服务器都会返回403状态码,网上找了很多资料 有权限的,有静态文件的,然而很多都没有什么卵 ...

  8. Ajax_HTTP请求以及响应

    什么是HTTP请求? 就是从用户的浏览器端向服务器端发送请求 一个HTTP请求一般由四个部分组成 1.HTTP请求的方法或者动作,比如GET或者POST请求 2.请求的URL,也就是请求的地址 3.请 ...

  9. LeetCode题解(14)--Longest Common Prefix

    https://leetcode.com/problems/longest-common-prefix/ 原题: Write a function to find the longest common ...

  10. UI类继承关系图