题目连接:http://codeforces.com/contest/1263/problem/F

题意:有n个设备,上和下分别连接着一颗树,上下两棵树每棵树的叶子节点连接一个设备,两棵树的根节点都是1,1是源点可以发电供给叶结点连接的设备,现在问最多删除多少条边可以保证从根结点1发电后仍然可以使得所有设备都有电?

如上图删除红色的边(5条)仍然可以保证所有设备能供电

思路:

因为是有上下两棵树,所以对于一个设备可以供电,那么删除上面的树一部分边,要么删除下面一部分边,根据题意,我们当然要删除最多的那一部分边。对于边,不太容易枚举,但由于树的特殊性,除根结点外,每个结点的入边只能是一条,即入度为1,我们可以考虑删除一个结点和其所连接的入边,然后来判断一下会影响哪些设备。假设这个节点被删除后,所影响的设备是设备 i 到设备 j 的所有设备,致使它们无法被供电,那我们可以用val[i][j]表示设备 i 到 设备 j 不能供电时,可以删除的最多的边数量,这个过程可以用dfs预处理去记录(具体看代码)

上下两颗树都dfs预处理完之后,得到了val数字,就可以dp了,设dp[i]表示对于前i个设备,最多可以删除多少条仍然可以供电

转移方程就比较简单了,dp[i] = max (dp[i] , dp[j] + val [ j+1 ] [ i ] ),j从0枚举到 i-1,最终dp[n]就是所求答案.

AC代码:

#include<iostream>
#include<stack>
#include<vector>
#include<algorithm>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
typedef long long ll;
const int maxn = 2e3+5;
struct node{
vector<int> next;
}g1[maxn],g2[maxn];
int val[maxn][maxn];
int size1[maxn],size2[maxn],l1[maxn],l2[maxn],r1[maxn],r2[maxn];//枚举可以延申的左右端点 和 边数
int dp[maxn];
void dfs_up(int cur){
if(cur != 1) size1[cur] = 1;
for(int i = 0;i<g1[cur].next.size();i++){
int v = g1[cur].next[i];
dfs_up(v);
l1[cur] = min(l1[cur],l1[v]);
r1[cur] = max(r1[cur],r1[v]);
size1[cur]+=size1[v];
}
val[l1[cur]][r1[cur]] = max(val[l1[cur]][r1[cur]],size1[cur]);
}
void dfs_down(int cur){
if(cur != 1) size2[cur] = 1;//如果不是根节点1,先+1条边,因为该节点上面必定连接一条边
for(int i = 0;i<g2[cur].next.size() ;i++){
int v = g2[cur].next[i];
dfs_down(v);
l2[cur] = min(l2[cur],l2[v]);
r2[cur] = max(r2[cur],r2[v]);
size2[cur]+=size2[v];
}
val[l2[cur]][r2[cur]] = max(val[l2[cur]][r2[cur]],size2[cur]);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n;cin>>n;
int a;cin>>a;
for(int i = 1;i<a;i++){
int pi;cin>>pi;
l1[i] = maxn,r1[i] = -1;
g1[pi].next.push_back(i+1);
}
l1[a] = maxn,r1[a] = -1;
for(int i = 1;i<=n;i++){
int xi;cin>>xi;
l1[xi] = i,r1[xi] = i;
}
int b;cin>>b;
for(int i = 1;i<b;i++){
int qi;cin>>qi;
l2[i] = maxn,r2[i] = -1;
g2[qi].next.push_back(i+1);
}
l2[b] = maxn,r2[b] = -1;
for(int i = 1;i<=n;i++){
int yi;cin>>yi;
l2[yi] = i,r2[yi] = i;
}
dfs_up(1),dfs_down(1);//上下两颗树各跑一遍dfs
for(int i = 0;i<=n;i++){
for(int j = 0;j<i;j++){
dp[i] = max(dp[i],dp[j]+val[j+1][i]);//n^2dp枚举
}
}
cout<<dp[n];
return 0;
}

codeforces div2_603 F. Economic Difficulties(树dfs预处理+dp)的更多相关文章

  1. Codeforces Round #603 (Div. 2)F. Economic Difficulties

    F. Economic Difficulties 题目链接: https://codeforces.com/contest/1263/problem/F 题目大意: 两棵树,都有n个叶子节点,一棵树正 ...

  2. Codeforces Round #603 (Div. 2) F. Economic Difficulties dp

    F. Economic Difficulties An electrical grid in Berland palaces consists of 2 grids: main and reserve ...

  3. [CF Round603 Div2 F]Economic Difficulties

    题目:Economic Difficulties 传送门:https://codeforces.com/contest/1263/problem/F 题意:给了两棵tree:Ta(拥有a个节点,节点编 ...

  4. Codeforces 835 F Roads in the Kingdom(树形dp)

    F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...

  5. Codeforces Round #603 F Economic Difficulties

    题目大意 给你两棵树,结点分别是1-A与1-B,然后给了N台设备,并且A树和B树的叶子结点(两棵树的叶子节点数量相同)都是链接电机的.问,最多可以删掉几条边使得每个设备都能连到任意一棵(或两棵)树的根 ...

  6. CodeForces 384E Propagating tree (线段树+dfs)

    题意:题意很简单么,给定n个点,m个询问的无向树(1为根),每个点的权值,有两种操作, 第一种:1 x v,表示把 x 结点加上v,然后把 x 的的子结点加上 -v,再把 x 的子结点的子结点加上 - ...

  7. codeforces 813C The Tag Game 树+dfs追击问题

    C. The Tag Gametime limit per test1 secondmemory limit per test256 megabytesinputstandard inputoutpu ...

  8. CodeForces 765 F Souvenirs 线段树

    Souvenirs 题意:给你n个数, m次询问, 对于每次一次询问, 求出询问区间内绝对值差值的最小值. 题解:先按查询的右端点从小到大sort一下,然后对于塞入一个数的时候, 就处理出所有左端点到 ...

  9. wannalfy 挑战赛8 F 白云的树(树形dp)

    链接:https://www.nowcoder.com/acm/contest/57/F 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524288K 64b ...

随机推荐

  1. final 和 static之间的区别和联系

    关键字final和关键字static两者的含义并不相似,但是笔者常常使用一段时间后就会忘记它们之间的区别,因为它俩总是相伴着出现.当只出现其中一个时,就对其代表的含义不甚清晰了.故而特地将相关知识点记 ...

  2. PHP0007:PHP基础-字符串

    php设置编码 用gbk编码识别utf8字符

  3. markdown转成word或者pdf

    利用typora软件 1.登陆官网下载软件 官网地址:https://typora.io/ 点击download 根据自己的电脑下载64位或者32位 2.安装软件 安装界面如下: 3.转换 3.1首先 ...

  4. Spark学习之路 (五)Spark伪分布式安装[转]

    JDK的安装 JDK使用root用户安装 上传安装包并解压 [root@hadoop1 soft]# tar -zxvf jdk-8u73-linux-x64.tar.gz -C /usr/local ...

  5. NOI Online能力测试游记:退役选手的自娱自乐

    2020年2月17日早上8点,CCF发布了关于举办NOI Online能力测试的通知. 为给选手提供一个锻炼的机会,CCF拟举办一场NOI Online能力测试.测试分为入门组和提高组,每组限额报名3 ...

  6. DataGridView只显示数据源中绑定的字段

    场景: 由于环境需要,在获取数据源的时候会获取多于DataGridView中绑定的字段,若不做任何处理,直接将数据源绑定到DataGridView上面,DataGridView就会将数据源中没有绑定的 ...

  7. PWA - 整体(未完)

    渐进式 Web 应用(PWA) 运用现代的 Web API 以及传统的渐进式增强策略来创建跨平台 Web 应用程序. PWA 的优势 可被发现 易安装 manifest(https://develop ...

  8. vjudge Lake Counting 搜索 水池 8方向

    原题链接https://vjudge.net/contest/331118#problem/A 题目: 现在有一个M*N的方阵,每个格子里面是.或者W,点代表水,然后如果在这个点的周围,即8个方向内还 ...

  9. 在linux系统中配置NVMe over FC

    在linux系统中配置NVMe over FC与配置NVMe over TCP类似,前5步操作请参考<在linux系统中配置NVMe over TCP>,网页连接如下: https://w ...

  10. VUE 路由参数改变重新刷新数据

    VUE 路由参数改变重新刷新数据 App.vue 里面使用路由,然后通过App.vue文件中的搜索功能搜索刷新路由文件中的列表. 修改 index.js 文件 首先在路由文件 index.js 文件中 ...