【BZOJ1040】骑士(动态规划)
2024-08-25 18:12:05
【BZOJ1040】骑士(动态规划)
题面
题解
对于每一组厌恶的关系
显然是连边操作
如果是一棵树的话
很显然的树型\(dp\)
但是,现在相当于有很多个基环
也就是在一棵树的基础上再加了一条边
这个时候怎么办,
暴力拆掉基环(拆掉任意一条边)
跑两遍\(dp\)
计算出强制不选两个点中某一个的最大值
此时就是这个基环的最大值
(不用拆掉所有的边,因为只要拆掉一条边之后可以用树型\(dp\)来控制)
可能存在多个联通块
所以要算多遍,然后求和
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 1200000
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
struct Line{int v,next;}e[MAX<<1];
int h[MAX],cnt=2;
int n,a[MAX];
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
long long f[MAX][2];
int U,V,L;
int fa[MAX],Cri[MAX],tot;
int getf(int x){return x==fa[x]?x:fa[x]=getf(fa[x]);}
void dfs(int u,int ff)
{
f[u][1]=a[u];f[u][0]=0;
for(int i=h[u];i;i=e[i].next)
{
if(i==L||i==(L^1))continue;
int v=e[i].v;
if(v==ff)continue;
dfs(v,u);
f[u][0]+=max(f[v][0],f[v][1]);
f[u][1]+=f[v][0];
}
}
int main()
{
n=read();
for(int i=1;i<=n;++i)fa[i]=i;
for(int i=1,u;i<=n;++i)
{
a[i]=read(),u=read();Add(u,i),Add(i,u);
if(getf(u)!=getf(i))fa[getf(u)]=getf(i);
else Cri[++tot]=cnt-1;
}
long long ans=0;
for(int i=1;i<=tot;++i)
{
long long ss=0;
U=e[Cri[i]].v;V=e[Cri[i]^1].v;
L=Cri[i];
dfs(U,0);ss=max(ss,f[U][0]);
dfs(V,0);ss=max(ss,f[V][0]);
ans+=ss;
}
printf("%lld\n",ans);
return 0;
}
最新文章
- MYSQL进阶,新手变司机
- python的__future__特性
- mysql TIMESTAMP 报错
- find / -name *.py | xargs grep ";domain"; | wc -l
- Redis认识
- 2 weekend110的HDFS的JAVA客户端编写 + filesystem设计思想总结
- 双缓冲技术(Double Buffering)(1、简介和源代码部分)
- 使用sae定时执行Python脚本
- hive load from hdfs出错
- 7、装饰模式(Decorator)
- 关于Cookie中不过滤“=”号的方法
- ImageMagick 使用经验
- DD XOFT虚拟键盘鼠标
- 【慕课网实战】Spark Streaming实时流处理项目实战笔记十六之铭文升级版
- bootstrap之表单和图片
- Conditional特性用法
- 01 - nginx - 安装、配置文件、默认网站、虚拟主机
- 学习MongoDB 四: MongoDB查询(一)
- 洛谷P2894[USACO08FEB]酒店Hotel(线段树)
- C++ STL 全排列函数详解