bzoj1040 基环树森林dp

时间:2022-01-16 05:19:12

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

  Z国的骑士团是一个很有*的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各
界的赞扬。最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的侵略战争。战火绵延五百里,在和平环境
中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一
个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具有打败邪恶*的能力的,但是骑士们互相之间往往有一
些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出
征的。战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有
的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的
情况),并且,使得这支骑士军团最具有战斗力。为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战
斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。 Input
  第一行包含一个正整数N,描述骑士团的人数。接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力
和他最痛恨的骑士。 Output
  应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。 Sample Input Sample Output Hint
N ≤ ,每名骑士的战斗力都是不大于 000的正整数。

题意

求解最大点独立集的大小,但是这个数据范围是不能求解的,仔细一看会发现题目给的是一片基环树森林,所以我们考虑对每一棵基环树进行树形dp,求他的总和。

求解基环树问题一般来说是将环看作广义上的根节点然后求解,对于这道题事实上唯一的限制条件就是环上两个相邻的点之间不能同时取到,所以我们考虑断开环变成一棵树,g[u]表示根节点为u时,u不取的最大值,所以单独一颗基环树的最大值就是环上任意边的两相邻点g[u],g[v]的较大值。

然后用简单树dp即可求解。

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
inline int read(){int now=;register char c=getchar();for(;!isdigit(c);c=getchar());
for(;isdigit(c);now=now*+c-'',c=getchar());return now;}
#define For(i, x, y) for(int i=x;i<=y;i++)
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x);
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x);
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
const double eps = 1e-;
const int maxn = 1e6 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
int N,M,K;
LL v[maxn];
LL f[maxn],g[maxn];
int head[maxn],tot;
struct Edge{
int to,next;
}edge[maxn * ];
void init(){
Mem(head,-); tot = ;
}
void add(int u,int v){
edge[tot].to = v; edge[tot].next = head[u];
head[u] = tot++;
}
int U,V,E;
bool vis[maxn];
void dfs(int t,int fa){
vis[t] = ;
for(int i = head[t]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == fa) continue;
if(vis[v]){
U = t; V = v;
E = i;
continue;
}
dfs(v,t);
}
}
void DP(int t,int fa,int del){
f[t] = v[t]; g[t] = ;
for(int i = head[t]; ~i; i = edge[i].next){
int v = edge[i].to;
if((i == del) || (v == fa) || ((i ^ ) == del)) continue;
DP(v,t,del);
g[t] += max(f[v],g[v]);
f[t] += g[v];
}
}
int main()
{
Sca(N); init();
For(i,,N){
Scl(v[i]); int x = read();
add(x,i); add(i,x);
}
LL ans = ;
For(i,,N){
if(!vis[i]){
dfs(i,);
DP(U,,E); LL MAX = g[U];
DP(V,,E); MAX = max(MAX,g[V]);
ans += MAX;
}
}
Prl(ans);
#ifdef VSCode
system("pause");
#endif
return ;
}

bzoj1040 基环树森林dp的更多相关文章

  1. BZOJ 1040 骑士 基环树 树形DP

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1040 题目大意: Z国的骑士团是一个很有*的组织,帮会中汇聚了来自各地的精英.他们劫 ...

  2. BZOJ 1040 &lbrack;ZJOI2008&rsqb;骑士 &lpar;基环树&plus;树形DP&rpar;

    <题目链接> 题目大意: Z国的骑士团是一个很有*的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...

  3. &lbrack;CF1027F&rsqb;Session in BSU&lbrack;最小基环树森林&rsqb;

    题意 有 \(n\) 门课程,每门课程可以选择在 \(a_i\) 或者 \(b_i\) 天参加考试,每天最多考一门,问最早什么时候考完所有课程. \(n\leq 10^6\). 分析 类似 [BZOJ ...

  4. &lbrack;BZOJ4883&rsqb;&lbrack;Lydsy1705月赛&rsqb;棋盘上的守卫&lbrack;最小基环树森林&rsqb;

    题意 有一大小为 \(n*m\) 的棋盘,要在一些位置放置一些守卫,每个守卫只能保护当前行列之一,同时在每个格子放置守卫有一个代价 \(w\) ,问要使得所有格子都能够被保护,需要最少多少的代价. \ ...

  5. 洛谷 P1453 城市环路 &lpar; 基环树树形dp &rpar;

    题目链接 题目背景 一座城市,往往会被人们划分为几个区域,例如住宅区.商业区.工业区等等.B市就被分为了以下的两个区域--城市中心和城市郊区.在着这两个区域的中间是一条围绕B市的环路,环路之内便是B市 ...

  6. bzoj4883 &lbrack;Lydsy1705月赛&rsqb;棋盘上的守卫 最小生成基环树森林

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4883 题解 每一行和每一列都必须要被覆盖. 考虑对于每一行和每一列都建立一个点,一行和一列之间 ...

  7. bzoj 1040&colon; &lbrack;ZJOI2008&rsqb;骑士【基环树&plus;树形dp】

    没考虑可以连着两个不选--直接染色了 实际上是基环森林,对于每棵基环树,dfs找出一个环边,然后断掉这条边,分别对这条边的两端点做一边treedp,取max加进答案里 treedp是设f[u]为选u点 ...

  8. 骑士 HYSBZ - 1040(基环树&plus;树形dp)

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

  9. CF875F Royal Questions&lbrack;最大生成基环树森林&rsqb;

    这题这场比赛一堆人秒切..果然还是我太菜了吗 题意:二分图,右边$m$个点每个点$i$向左边有且仅有两条连边,边权都是$a_i$.求最大匹配. 一个朴素思想,二分图匹配,用贪心带匈牙利搞一搞,但是复杂 ...

随机推荐

  1. WebApi接口 - 如何在应用中调用webapi接口

    很高兴能再次和大家分享webapi接口的相关文章,本篇将要讲解的是如何在应用中调用webapi接口:对于大部分做内部管理系统及类似系统的朋友来说很少会去调用别人的接口,因此可能在这方面存在一些困惑,希 ...

  2. &period;NET Framework 4 中的并行编程9---线程安全集合类

    原文转载自:http://www.cnblogs.com/xray2005/archive/2011/10/11/2206745.html 在.Net 4中,新增System.Collections. ...

  3. 整理的Unity导出安卓工程利用ANT进行多渠道批量打包APK

    Unity导出的安卓工程利用ant进行多渠道循环批量打包 一:设置JAVA环境变量 做android开发的配置这个是基础. win7 下配置java环境变量,下面是链接 http://www.cnbl ...

  4. Delphi 调试WEBService程序(ISAPI或CGI) 把Web App Debugger executable转换成 ISAPI&sol;NSAPI

      1.新建一个web工程,请选中最下面一项:Web App Debugger executable,Coclass name我们设为demo1: 2.在弹出的WebModule2中右击,在弹出的Ac ...

  5. java--类继承和实现的接口中含有相同的方法

    首先,说一下,当某一个类实现了两个接口的时候,两个接口中存在两个相同的方法,在实现的类中只需实现一个方法的方法体. 当一个类继承一个类,并且实现一个或者多个接口的时候,其中,父类和父接口中存在相同的方 ...

  6. C语言第02次作业--循环结构

    1.本章学习总结 1.1思维导图 1.2本章学习体会及代码量学习体会 1.2.1学习体会 1- 经过这两周的学习,我深切地体会C语言非常的难(对于我而言).大部分情况都是题目不理解和没有思路,或者编译 ...

  7. Privoxy将Socks代理转化HTTP代理

    使用步骤 安装Privoxy sudo pacman -S privoxy # Arch Linux 创建配置文件 mkdir -p ~/.config/privoxy 向~/.config/priv ...

  8. &lbrack;转&rsqb; 设置div的overflow&colon;scroll&comma;但是在手机上滑动的时候有点卡顿

    设置div的overflow:scroll,但是在手机上滑动的时候有点卡顿,所以在这个div上加一个css: -webkit-overflow-scrolling : touch; 在苹果手机上使用- ...

  9. MySQL升级后1728错误解决方案

    MySQL升级后1728错误解决方案 错误 # 1728,Cannot load from mysql.proc. The table is probably corrupted 造成原因:MySQL ...

  10. SQL Server -&gt&semi;&gt&semi; 数据类型不一致比较时的隐式转换

    当使用操作符进行比较的时候,两边数据类型不一致的情况下,数据类型优先级别低的会往优先级别高的发生隐式转换.下面的参考链接是优先级别列表. 参考: Data Type Precedence (Trans ...