【BZOJ】【1040】【ZJOI2008】骑士
树形DP/基环树DP
我掉坑掉了好多……
这题图比较特殊,每个连通块都是一棵基环树(我一开始以为图是连通的了……sigh,我说为什么网上的题解都要累加ans……),那么对于一棵基环树,我们先dfs找到这个环,再随便断一条环上的边使它变成一棵树,就可以TreeDP啦~但是有个问题:这两个点不能同时选,所以:假设A不选,那么就以A为根做一次DP,此时B选不选都可以,取tmp=f[A][0](不选A的最大收益);再假设B不选,以B为根再做一次DP,取f[B][0],那么tmp和f[B][0]的较大值就是这个连通块的最大收益。
但是……有种奇特的环是二元环……说人话就是重边QAQ这种情况下我原来那种判to!=fa[x]的方法就没法找到环了……我就加了个特判,如果环大小为0就直接对根TreeDP算答案= =
我的方法时空复杂度好像比较高……但个人感觉还是蛮好懂的
/**************************************************************
Problem: 1040
User: Tunix
Language: C++
Result: Accepted
Time:2152 ms
Memory:64836 kb
****************************************************************/ //BZOJ 1040
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
inline int getint(){
int v=,sign=; char ch=getchar();
while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
return v*sign;
}
const int N=1e6+,INF=~0u>>;
typedef long long LL;
/******************tamplate*********************/
int to[N<<],next[N<<],head[N],cnt;
void add(int x,int y){
to[++cnt]=y; next[cnt]=head[x]; head[x]=cnt;
to[++cnt]=x; next[cnt]=head[y]; head[y]=cnt;
}
/********************edge***********************/
int n,a[N],circle[N],tot;
LL f[N][],ans,v[N];
int dfn[N],low[N],fa[N],dfs_clock;
bool vis[N];
void dfs(int x){
dfn[x]=low[x]=++dfs_clock;
for(int i=head[x];i;i=next[i])
if (to[i]!=fa[x]){
if (!dfn[to[i]]){
fa[to[i]]=x;
dfs(to[i]);
low[x]=min(low[x],low[to[i]]);
}else low[x]=min(low[x],dfn[to[i]]);
}
if (low[x]<dfn[x]) circle[++tot]=x;
}
void Tree_DP(int x){
vis[x]=; f[x][]=v[x]; f[x][]=;
for(int i=head[x];i;i=next[i])
if (!vis[to[i]]){
Tree_DP(to[i]);
f[x][]+=f[to[i]][];
f[x][]+=max(f[to[i]][],f[to[i]][]);
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("1040.in","r",stdin);
freopen("1040.out","w",stdout);
#endif
n=getint();
F(i,,n){
v[i]=getint();
a[i]=getint(); add(i,a[i]);
}
F(i,,n) if (!dfn[i]){
dfs(i); LL tmp;
// F(i,1,tot) printf("%d ",circle[i]);puts("");
if (tot){
memset(vis,,sizeof vis);
Tree_DP(circle[]);
tmp=f[circle[]][];
memset(vis,,sizeof vis);
Tree_DP(circle[]);
tmp=max(tmp,f[circle[]][]);
}else{
Tree_DP(i);
tmp=max(f[i][],f[i][]);
}
ans+=tmp; tot=;
}
printf("%lld\n",ans);
return ;
}
1040: [ZJOI2008]骑士
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 2232 Solved: 857
[Submit][Status][Discuss]
Description
Z
国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。最近发生了一件可怕的事情,邪恶的Y国发动
了一场针对Z国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的Z国又怎能抵挡的住Y国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就
像期待有一个真龙天子的降生,带领正义打败邪恶。骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己
最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你
一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支
骑士军团最具有战斗力。为了描述战斗力,我们将骑士按照1至N编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。
Input
第一行包含一个正整数N,描述骑士团的人数。接下来N行,每行两个正整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。
Output
应包含一行,包含一个整数,表示你所选出的骑士军团的战斗力。
Sample Input
10 2
20 3
30 1
Sample Output
HINT
对于100%的测试数据,满足N ≤ 1 000 000,每名骑士的战斗力都是不大于 1 000 000的正整数。
Source
【BZOJ】【1040】【ZJOI2008】骑士的更多相关文章
- BZOJ 1040: [ZJOI2008]骑士 基环加外向树
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1190 Solved: 465[Submit][Status] ...
- bzoj 1040: [ZJOI2008]骑士 環套樹DP
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1755 Solved: 690[Submit][Status] ...
- bzoj 1040: [ZJOI2008]骑士 树形dp
题目链接 1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3054 Solved: 1162[Submit][S ...
- [BZOJ 1040][ZJOI2008]骑士
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5403 Solved: 2060[Submit][Status ...
- Bzoj 1040 [ZJOI2008]骑士 题解
1040: [ZJOI2008]骑士 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5368 Solved: 2044[Submit][Status ...
- [BZOJ 1040] [ZJOI2008] 骑士 【基环+外向树DP】
题目链接:BZOJ - 1040 题目分析 这道题目的模型就是一个图,不一定联通,每个连通块的点数等于边数. 每个连通块都是一个基环+外向树.即树上增加了一条边. 如果是树,就可以直接树形DP了.然而 ...
- bzoj 1040 [ZJOI2008]骑士(基环外向树,树形DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题意] 给一个基环森林,每个点有一个权值,求一个点集使得点集中的点无边相连且权 ...
- BZOJ 1040: [ZJOI2008]骑士(基环树dp)
http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题意: 思路: 这是基环树,因为每个人只会有一个厌恶的人,所以每个节点只会有一个父亲节点,但是 ...
- BZOJ 1040: [ZJOI2008]骑士 | 在基环外向树上DP
题目: http://www.lydsy.com/JudgeOnline/problem.php?id=1040 题解: 我AC了 是自己写的 超开心 的 考虑断一条边 这样如果根节点不选答案一定正确 ...
- BZOJ 1040 [ZJOI2008]骑士 (基环树+树形DP)
<题目链接> 题目大意: Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发动了一场针对Z国的 ...
随机推荐
- AppSetting ,connectionStrings配置节
<appSettings> <!-- 当前使用的学校代码 --> <add key="DefaultCompanyID" value="cs ...
- HBase数据导出到HDFS
一.目的 把hbase中某张表的数据导出到hdfs上一份. 实现方式这里介绍两种:一种是自己写mr程序来完成,一种是使用hbase提供的类来完成. 二.自定义mr程序将hbase数据导出到hdfs上 ...
- javascript组件化(转)
javascript组件化(转) By purplebamboo 3月 16 2015 更新日期:3月 23 2015 文章目录 1. 最简陋的写法 2. 作用域隔离 3. 面向对象 4. 抽象出ba ...
- mysql 语句其它及优化
将检索到的数据保存到文件 Select * into outfile ‘文件地址’ from tabname; 生成的文件以制表符区分字段,以换行符区分记录 为满足特殊需求会采用不同的分割方式. 支 ...
- 主键、外键、超键、候选键的区别【Written By KillerLegend】
先说一下属性的定义: 表的每一行对应一个元组,表的每一列对应一个域.由于域可以相同,为了加以区分,必须对每列起一个唯一的名字,称为属性(Attribute). 再来看看几个键的定义: 超键:在关系模式 ...
- Css 书写规范【转】
1. 不同浏览器元素的默认属性有所不同,使用Reset可重置浏览器元素的一些默认属性,以达到浏览器的兼容. /** 清除内外边距 **/ body, h1, h2, h3, h4, h5, h6, h ...
- 第十三章 调试及安全性(In .net4.5) 之 验证程序输入
1. 概述 本章介绍验证程序输入的重要性以及各种验证方法:Parse.TryParse.Convert.正则表达式.JavaScriptSerializer.XML Schemas. 2. 主要内容 ...
- Python学习教程(learning Python)--3.3.2 Python的关系运算
如果if的condition不用布尔表达式来做条件判断而采用关系表达式,实际上关系表达式运算的结果要么是True要么是False.下面我们先了解一些有关关系运算符的基础知识,如下表所示. 做个小程序测 ...
- instanceof、==号、Objetc类
1)instanceof: 判断某个对象是否为某个类的实例,注意多态的运用,一个父类引用指向子类的对象,根据继承,子类就是父类,所以子类也可以看做是父类的一个实例. 形式:引用 instanceof ...
- linux C socket
socket套接字和管道同样可以提供进程内通信.但套接字更胜一筹,不同的进程可以跨越不同的主机(说白了,支持网络通信).使用套接字的知名程序:telnet.rlogin.ftp等. 你需要知道的一些基 ...