原题

给出n个点n条边和每个点的点权,一条边的两个断点不能同时选择,问最大可以选多少。


//图是一张基环外向树森林

是不是很像舞会啊~

就是多了一条边。

所以我们考虑一下对于一棵基环外向树,拆掉一条在环上的边,变成一棵树。在这个树上以断边的一个断点为根,跑舞会,就得到了这棵树的最大值(根选和根不选了两种)。考虑到对于拆下来的内一条边,也要满足断点不能同时选择,所以此时得到的答案中,根不选一定是正确的,但是根选不一定是正确的(因为我们不知道此刻另一个断点是否被选择)。

那么我们强制该点不选,然后更新至根选的状态即可。

#include<cstdio>
#include<algorithm>
#define N 1000010
typedef long long ll;
using namespace std;
int n,a[N],f[N],head[N],ecnt=1,cnt[N];
ll dp[N][2],ans;
bool vis[N];
struct hhh
{
int to,next;
}edge[N]; int read()
{
int ans=0,fu=1;
char j=getchar();
for (;j<'0' || j>'9';j=getchar()) if (j=='-') fu=-1;
for (;j>='0' && j<='9';j=getchar()) ans*=10,ans+=j-'0';
return ans*fu;
} void add(int u,int v)
{
edge[ecnt].to=v;
edge[ecnt].next=head[u];
head[u]=ecnt++;
} void dfs(int x)//经典dp
{
vis[x]=1;
dp[x][1]=a[x];
for (int i=head[x];i;i=edge[i].next)
if (!vis[edge[i].to])
{
dfs(edge[i].to);
dp[x][0]+=max(dp[edge[i].to][0],dp[edge[i].to][1]);
dp[x][1]+=dp[edge[i].to][0];
}
} void DP(int x)
{
int root;
for (root=x;cnt[root]!=x;root=f[root])
cnt[root]=x;
dfs(root);
x=f[root];//x为当前根,那么不在树上的那条边就是x和f[x]的边,所以强制f[x]不选
dp[x][1]=dp[x][0];
for (x=f[x];x!=root;x=f[x])
{
dp[x][0]=0;dp[x][1]=a[x];
for (int i=head[x];i;i=edge[i].next)
{
dp[x][0]+=max(dp[edge[i].to][0],dp[edge[i].to][1]);
dp[x][1]+=dp[edge[i].to][0];
}
}
dp[root][1]=a[root];
for (int i=head[root];i;i=edge[i].next)
dp[root][1]+=dp[edge[i].to][0];//强制根选,则+=儿子们都不选
ans+=max(dp[root][0],dp[root][1]);//取当前基环外向树的最大值
} int main()
{
n=read();
for (int i=1;i<=n;i++)
a[i]=read(),f[i]=read(),add(f[i],i);
for (int i=1;i<=n;i++)//基环外向树森林
if (!vis[i]) DP(i);
printf("%lld\n",ans);
return 0;
}

[bzoj] 1040 骑士 || 基环外向树dp的更多相关文章

  1. HYSBZ 1040 骑士 (基环外向树DP)

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

  2. 1040: [ZJOI2008]骑士~基环外向树dp

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

  3. 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士

    基环外向树dp竟然如此简单…… Description Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬.最近发生了一件可怕的事情,邪恶的Y国发 ...

  4. 【BZOJ1040】[ZJOI2008] 骑士(基环外向树DP)

    点此看题面 大致题意: 给你一片基环外向树森林,如果选定了一个点,就不能选择与其相邻的节点.求选中点的最大权值和. 树形\(DP\) 此题应该是 树形\(DP\) 的一个升级版:基环外向树\(DP\) ...

  5. [BZOJ 1040] [ZJOI2008] 骑士 【基环+外向树DP】

    题目链接:BZOJ - 1040 题目分析 这道题目的模型就是一个图,不一定联通,每个连通块的点数等于边数. 每个连通块都是一个基环+外向树.即树上增加了一条边. 如果是树,就可以直接树形DP了.然而 ...

  6. BZOJ1040 骑士 基环外向树

    1040: [ZJOI2008]骑士 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6421  Solved: 2544[Submit][Status ...

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

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

  8. bzoj 1040 [ZJOI2008]骑士(基环外向树,树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1040 [题意] 给一个基环森林,每个点有一个权值,求一个点集使得点集中的点无边相连且权 ...

  9. 洛谷 2921 记忆化搜索 tarjan 基环外向树

    洛谷 2921 记忆化搜索 tarjan 传送门 (https://www.luogu.org/problem/show?pid=2921) 做这题的经历有点玄学,,起因是某个random题的同学突然 ...

随机推荐

  1. ansible基础配置使用(一)

    test  test  test

  2. Ubuntu目录与权限

    Ubuntu目录 / /bin /sbin /boot /etc /mnt /home d :directory - :file b :block  磁盘以块进行 l :link Ubuntu权限 U ...

  3. 关于Python 中的 if 语句

    学习Python,最开始我们都是先从函数学起,Python教程中有很多函数,if算是其中之一. 可能最为人所熟知的编程语句就是 if 语句了.例如: >>> >>> ...

  4. Python全栈 项目(电子词典、协程、pdb调试)

    后面我就不截图了 大家还是看原文吧                          https://yq.aliyun.com/articles/629534 . ................. ...

  5. spark写入ES(动态模板)

    使用es-hadoop插件,主要使用elasticsearch-spark-20_2.11-6.2.x.jar 官网:https://www.elastic.co/guide/en/elasticse ...

  6. 使用Zabbix监控rabbitmq服务

    添加rabbitmq脚本 [root@controller rabbitmq]# cd /etc/zabbix/script/rabbitmq [root@controller rabbitmq]# ...

  7. DeepLearning Intro - sigmoid and shallow NN

    This is a series of Machine Learning summary note. I will combine the deep learning book with the de ...

  8. 线性代数之——正交矩阵和 Gram-Schmidt 正交化

    这部分我们有两个目标.一是了解正交性是怎么让 \(\hat x\) .\(p\) .\(P\) 的计算变得简单的,这种情况下,\(A^TA\) 将会是一个对角矩阵.二是学会怎么从原始向量中构建出正交向 ...

  9. 3.azkaban3.0测试

    测试目标 azkaban多executor下flow的分配方式 azkaban可以同时执行的flow\job个数 azkaban单个job最小使用的内存 相关配置 executor最大线程数: exe ...

  10. 将footer固定在页面最下方

    方法一: HTML结构: <div id="id_wrapper"> <div id="id_header"> Header Block ...