【刷题】BZOJ 1487 [HNOI2009]无归岛
Description
Neverland是个神奇的地方,它由一些岛屿环形排列组成,每个岛上都生活着之中与众不同的物种。但是这些物种都有一个共同的生活习性:对于同一个岛上的任意两个生物,他们有且仅有一个公共朋友,即对同一岛上的任意两个生物a和b有且仅有一个生物c既是a的朋友也是b的朋友,当然某些岛上也可能会只有一个生物孤单地生活着。这一习性有一个明显的好处,当两个生物发生矛盾的时候,他们可以请那个唯一的公共朋友来裁决谁对谁错。
另外,岛与岛之间也有交流,具体来说,每个岛都会挑选出一个最聪明的生物做代表,然后这个生物与他相邻的两个岛的代表成为朋友。
不行的是,A世界准备入侵Neverland,作为Neverland的守护者,Lostmonkey想知道在一种比较坏的情况下Never的战斗力。因为和朋友并肩作战,能力会得到提升,所以Lostmonkey想知道在不选出一对朋友的情况下Neverland的最大战斗力。即选出一些生物,且没有一对生物是朋友,并且要求它们的战斗力之和最大。
Input
第一行包含用空格隔开的两个整数n和m,分别表示Neverland的生物种数和朋友对数。接下来的m行描述所有朋友对,具体来说,每行包含用空格隔开的两个整数a和b,表示生物a和生物b是朋友(每对朋友只出现一次)。第m+2行包含用空格隔开的n个整数,其中第i个整数表示生物i的战斗力Ai。输入数据保证4<=n<=100000,1<=a,b<=n,1<=m<=200000,-1000<=Ai<=1000.
Output
仅包含一个整数,表示满足条件的最大战斗力。
Sample Input
6 7
1 2
2 3
3 4
4 1
3 6
3 5
5 6
20 10 30 15 20 10
Sample Output
50
【样例说明】
有四个岛,生物1在1号岛,生物2在2号岛,生物3、5、6在3号岛,生物4在4号岛。
HINT
NeverLand这个单词在“小飞侠彼得潘”中译为梦幻岛,在这却成为无归岛,真是汗啊.
Solution
题目描述好奇怪啊
就是要求仙人掌的最大点权独立集
将环和树的分开dp
如果是一个树,那么就是个入门dp,\(f_{u,0/1}\) 代表 \(u\) 这个点选或不选的最优答案,转移很简单
对于一个环,把环上的点拿出来,找任意一条边,强制这条边的一端不选,线性dp一下,再强制另一段不选,线性dp一下,将两次dp的答案取最大更新到 \(root\) 就好了
#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10,MAXM=200000+10,inf=0x3f3f3f3f;
int n,m,val[MAXN],beg[MAXN],nex[MAXM<<1],to[MAXM<<1],DFN[MAXN],LOW[MAXN],Visit_Num,e,f[MAXN][2],g[MAXN][2],ex[2],fa[MAXN],cnt,a[MAXN],ans;
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
}
inline void loop(int root,int x)
{
a[cnt=1]=x;
for(register int i=x;i!=root;i=fa[i])a[++cnt]=fa[i];
g[x][0]=f[x][0],g[x][1]=-inf;
for(register int i=2;i<=cnt;++i)
{
g[a[i]][0]=f[a[i]][0]+max(g[a[i-1]][0],g[a[i-1]][1]);
g[a[i]][1]=f[a[i]][1]+g[a[i-1]][0];
}
ex[0]=g[root][0],ex[1]=g[root][1];
g[x][0]=f[x][0],g[x][1]=f[x][1];
for(register int i=2;i<=cnt;++i)
{
g[a[i]][0]=f[a[i]][0]+max(g[a[i-1]][0],g[a[i-1]][1]);
g[a[i]][1]=f[a[i]][1]+g[a[i-1]][0];
}
chkmax(ex[0],g[root][0]);
f[root][0]=ex[0],f[root][1]=ex[1];
}
inline void Tarjan(int x,int p)
{
DFN[x]=LOW[x]=++Visit_Num;fa[x]=p;
f[x][0]=0,f[x][1]=val[x];
for(register int i=beg[x];i;i=nex[i])
if(to[i]==p)continue;
else if(!DFN[to[i]])
{
Tarjan(to[i],x);
chkmin(LOW[x],LOW[to[i]]);
if(LOW[to[i]]>DFN[x])
{
f[x][0]+=max(f[to[i]][1],f[to[i]][0]);
f[x][1]+=f[to[i]][0];
}
}
else if(DFN[to[i]]<DFN[x])chkmin(LOW[x],DFN[to[i]]);
for(register int i=beg[x];i;i=nex[i])
if(to[i]==p)continue;
else if(fa[to[i]]!=x&&DFN[to[i]]>DFN[x]&&LOW[to[i]]<=DFN[x])loop(x,to[i]);
}
int main()
{
read(n);read(m);
for(register int i=1;i<=m;++i)
{
int u,v;read(u);read(v);
insert(u,v);insert(v,u);
}
for(register int i=1;i<=n;++i)read(val[i]);
for(register int i=1;i<=n;++i)
if(!DFN[i])Tarjan(i,0),ans+=max(f[i][0],f[i][1]);
printf("%d\n",ans);
return 0;
}
【刷题】BZOJ 1487 [HNOI2009]无归岛的更多相关文章
- 【BZOJ1487】[HNOI2009]无归岛(动态规划)
[BZOJ1487][HNOI2009]无归岛(动态规划) 题面 BZOJ 洛谷 题解 哪来的这么多废话啊,直接说一个仙人掌得了. 然后就是要你求仙人掌最大独立集了.(随便蒯份原来的代码就过了) 不过 ...
- P4410 [HNOI2009]无归岛
P4410 [HNOI2009]无归岛 显然这还是一个仙人掌图 对于同一个岛上的任意两个生物,他们有且仅有一个公共朋友 要求求最大独立集,和树形dp一样,遇到环时单独提出来处理一下就好了 #inclu ...
- bzoj1487 [HNOI2009]无归岛
Description Neverland是个神奇的地方,它由一些岛屿环形排列组成,每个岛上都生活着之中与众不同的物种.但是这些物种都有一个共同的生活习性:对于同一个岛 上的任意两个生物,他们有且仅有 ...
- 【BZOJ1487】[HNOI2009]无归岛(仙人掌 DP)
题目: BZOJ1487 分析: 题目中给定的图一定是一棵仙人掌(每条边最多属于一个环),证明如下: 先考虑单独一个岛的情况.第一,一个岛一定是一张「弦图」,即任意一个大小超过 3 的环都至少有 1 ...
- [HNOI2009]无归岛
Description Neverland是个神奇的地方,它由一些岛屿环形排列组成,每个岛上都生活着之中与众不同的物种.但是这些物种都有一个共同的生活习性:对于同一个岛上的任意两个生物,他们有且仅有一 ...
- 2019.02.07 bzoj1487: [HNOI2009]无归岛(仙人掌+树形dp)
传送门 人脑转化条件过后的题意简述:给你一个仙人掌求最大带权独立集. 思路:跟这题没啥变化好吗?再写一遍加深记忆吧. 就是把每个环提出来分别枚举环在图中的最高点选还是不选分别dpdpdp一下即可,时间 ...
- 【题解】HNOI2009无归岛
这题真的是无语了,在哪个岛上根本就没有任何的用处……不过我是画了下图,感受到一定是仙人掌,并不会证.有谁会证的求解…… 如果当做仙人掌来做确实十分的简单.只要像没有上司的舞会一样树形dp就好了,遇到环 ...
- Luogu-4410 [HNOI2009]无归岛
裸的仙人掌最大独立子集,结果一个zz的错误让我调了好久... \(-inf\)开始设为\(0x7fffffff\)结果\(A_i\)有负数一加就炸了 #include<cstdio> #i ...
- BZOJ1487 [HNOI2009]无归岛 【仙人掌dp】
题目链接 BZOJ1487 题解 就是一个简单的仙人掌最大权独立集 还是不会圆方树 老老实实地树形Dp + 环处理 #include<iostream> #include<cstdi ...
随机推荐
- 将公钥部署到远程Git仓库(coding.net)
步骤: 1.下载git通用客户端并且安装. 2.右键,在弹出的对话框中选择Git Bash 3.创建本地ssha)在弹出的终端输入ssh-keygen -t rsa -C "username ...
- SSIS ->> Excel Destination无法接受大于255个字符长度的字符字段
从下文的链接中找到一些背景,因为Excel会以前8行作为参考,如果某个字段前8行的最长长度没有超过255个字符,就会报错.如果知道某个字段属于描述性字段,而且字段的数据长度很可能超过255个字符长度, ...
- 20155235 《网络攻防》 实验五 MSF基础应用
20155235 <网络攻防> 实验五 MSF基础应用 实验内容 一个主动攻击实践,如ms08_067; (1分) 一个针对浏览器的攻击,如ms11_050:(1分) 一个针对客户端的攻击 ...
- EZ 2018 04 21 NOIP2018 模拟赛(九)
终于停止了掉Rating的浪潮! 猥琐的链接 这次200分才Rank10,而且很多人并列 庆幸T2最后20分钟发现期望的算法打错了,然后拿到了50pts,250收场 T1 水题*1 这道题不仅做过,而 ...
- 【php增删改查实例】第八节 - 部门管理模块(编写PHP程序)
首先,在同级目录新建一个query.php文件: 接着,去刷新页面,打开F12,NetWork,看看当前的请求能不能走到对应的php文件? 这就说明datagrid确实能够访问到query.php 只 ...
- CS229笔记:生成学习算法
在线性回归.逻辑回归.softmax回归中,学习的结果是\(p(y|x;\theta)\),也就是给定\(x\)的条件下,\(y\)的条件概率分布,给定一个新的输入\(x\),我们求出不同输出的概率, ...
- Join 和 Apply 用法全解
在关系型数据库系统中,为了满足第三范式(3NF),需要将满足“传递依赖”的表分离成单独的表,通过Join 子句将相关表进行连接,Join子句共有三种类型:外连接,内连接,交叉连接:外连接分为:left ...
- JQuery快速入门-操作元素的属性和样式
我们在学习JavaScript时,详细介绍了DOM对象.从DOM树可以得知,对DOM的操作,主要包括:元素的属性.内容.值.CSS. 一.元素属性的操作 在 jQuery 中,可以对元素的属性执行获取 ...
- Js_cookie保存登录名
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head ...
- Docker部署Registry私有镜像库
拉取镜像 docker pull registry:2.6.2 生成账号密码文件,这里采用htpasswd方式认证 docker run --rm --entrypoint htpasswd re ...