zoukankan      html  css  js  c++  java
  • Codeforces Round #603 (Div. 2)F. Economic Difficulties

    F. Economic Difficulties

    题目链接:

    https://codeforces.com/contest/1263/problem/F

    题目大意:

    两棵树,都有n个叶子节点,一棵树正着放,一棵树倒着放,叶子节点从左到右对应装置1,2,3,4...n,问最多能删掉多少条边,使得装置能与两棵树任意一个根节点1相连。

    解题思路:

    mp[ i ][ j ]是装置 i 到 j 这段区间删除这段连续区间所能删除的最大边数,两个图分开看,算出每一个图中如果不连通这段区间对应的叶子节点所能删除的最大边数,取这两个图的最大值就是mp[ i ][ j ]。dp[ i ]代表前 i 个装置中的最大删除数,因此可以推出递推式dp[ i ]=max(dp[ i ],dp[j] + mp[ j ][ i ] ) 其中j是从0 - i。

    代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int N=3e3;
     4 const int maxn=1e9+7;
     5 const int minn=0; 
     6 vector<int>arr[N];//存图 
     7 int sz[N];//记录当删除这个点后最多能删除多少条边 
     8 int L[N],R[N];//记录第i个节点包含的设备区间中的最左端与最右端 
     9 int mp[N][N];//记录选取任意连续区间的设备并删除,可以删除最多几条边(连续是指删除的边在同一个图中)
    10 int dp[N];
    11  
    12 int dfs(int a,int pre){
    13     if(a!=1){//每个点都代表他上方的那条边,1的上方没有边 
    14         sz[a]=1;    
    15     }
    16     for(int i=0;i<arr[a].size();i++){
    17         if(arr[a][i]!=pre){
    18             dfs(arr[a][i],a);
    19             sz[a]+=sz[arr[a][i]];//记录删除这个点会删除多少条边 
    20             L[a]=min(L[a],L[arr[a][i]]);//这个点代表区间的左端点 
    21             R[a]=max(R[a],R[arr[a][i]]);//右端点 
    22         }    
    23     }
    24     mp[L[a]][R[a]]=max(mp[L[a]][R[a]],sz[a]);//记录这个区间的最大删除边数 
    25 }
    26 
    27 int main(){
    28     int n,a,b,v;
    29     cin>>n;
    30     for(int i=0;i<2;i++){
    31         scanf("%d",&a);
    32         for(int i=1;i<=N;i++){
    33             arr[i].clear();
    34             L[i]=maxn;//初始化无穷大 
    35             R[i]=minn;//0 
    36         }
    37         for(int i=1;i<a;i++){//存图 
    38             scanf("%d",&v);
    39             arr[v].push_back(i+1); 
    40             arr[i+1].push_back(v);
    41         }
    42         for(int i=1;i<=n;i++){
    43             scanf("%d",&v);//这个点代表的装置区间为i 
    44             R[v]=L[v]=i;
    45         }
    46         sz[1]=0;
    47         dfs(1,0);
    48     }
    49     dp[0]=0;
    50     dp[1]=mp[1][1];
    51     for(int i=2;i<=n;i++){
    52         for(int j=0;j<=i;j++){
    53             dp[i]=max(dp[i],dp[j]+mp[j+1][i]); 
    54         }
    55     }
    56     cout<<dp[n]<<endl;
    57     return 0;
    58 } 
  • 相关阅读:
    WPF DataGrid ListView等控件Binding LINQ数据源
    WPF自定义命令
    vb.net与FLASH的完美结合
    [音乐欣赏]鲍家街43号 汪峰 小鸟
    MSGRID的填充
    听!是谁在唱歌
    学习用的几个英文单词
    [学习日记]三层结构
    有关从文件完整路径中提取文件名的方法
    有关TABCONTROL选项卡的动态选择方法
  • 原文地址:https://www.cnblogs.com/meanttobe/p/12023811.html
Copyright © 2011-2022 走看看